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 #define WINCE_DELETION_ATTEMPTS 3 610 winceDestroyLock(pFile); 611 if( pFile->zDeleteOnClose ){ 612 int cnt = 0; 613 while( 614 DeleteFileW(pFile->zDeleteOnClose)==0 615 && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff 616 && cnt++ < WINCE_DELETION_ATTEMPTS 617 ){ 618 Sleep(100); /* Wait a little before trying again */ 619 } 620 free(pFile->zDeleteOnClose); 621 } 622 #endif 623 OpenCounter(-1); 624 return rc ? SQLITE_OK : SQLITE_IOERR; 625 } 626 627 /* 628 ** Some microsoft compilers lack this definition. 629 */ 630 #ifndef INVALID_SET_FILE_POINTER 631 # define INVALID_SET_FILE_POINTER ((DWORD)-1) 632 #endif 633 634 /* 635 ** Read data from a file into a buffer. Return SQLITE_OK if all 636 ** bytes were read successfully and SQLITE_IOERR if anything goes 637 ** wrong. 638 */ 639 static int winRead( 640 sqlite3_file *id, /* File to read from */ 641 void *pBuf, /* Write content into this buffer */ 642 int amt, /* Number of bytes to read */ 643 sqlite3_int64 offset /* Begin reading at this offset */ 644 ){ 645 LONG upperBits = (offset>>32) & 0x7fffffff; 646 LONG lowerBits = offset & 0xffffffff; 647 DWORD rc; 648 DWORD got; 649 winFile *pFile = (winFile*)id; 650 assert( id!=0 ); 651 SimulateIOError(return SQLITE_IOERR_READ); 652 OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype); 653 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 654 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ 655 return SQLITE_FULL; 656 } 657 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ 658 return SQLITE_IOERR_READ; 659 } 660 if( got==(DWORD)amt ){ 661 return SQLITE_OK; 662 }else{ 663 memset(&((char*)pBuf)[got], 0, amt-got); 664 return SQLITE_IOERR_SHORT_READ; 665 } 666 } 667 668 /* 669 ** Write data from a buffer into a file. Return SQLITE_OK on success 670 ** or some other error code on failure. 671 */ 672 static int winWrite( 673 sqlite3_file *id, /* File to write into */ 674 const void *pBuf, /* The bytes to be written */ 675 int amt, /* Number of bytes to write */ 676 sqlite3_int64 offset /* Offset into the file to begin writing at */ 677 ){ 678 LONG upperBits = (offset>>32) & 0x7fffffff; 679 LONG lowerBits = offset & 0xffffffff; 680 DWORD rc; 681 DWORD wrote; 682 winFile *pFile = (winFile*)id; 683 assert( id!=0 ); 684 SimulateIOError(return SQLITE_IOERR_WRITE); 685 SimulateDiskfullError(return SQLITE_FULL); 686 OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype); 687 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 688 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ 689 return SQLITE_FULL; 690 } 691 assert( amt>0 ); 692 while( 693 amt>0 694 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 695 && wrote>0 696 ){ 697 amt -= wrote; 698 pBuf = &((char*)pBuf)[wrote]; 699 } 700 if( !rc || amt>(int)wrote ){ 701 return SQLITE_FULL; 702 } 703 return SQLITE_OK; 704 } 705 706 /* 707 ** Truncate an open file to a specified size 708 */ 709 static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ 710 LONG upperBits = (nByte>>32) & 0x7fffffff; 711 LONG lowerBits = nByte & 0xffffffff; 712 winFile *pFile = (winFile*)id; 713 OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); 714 SimulateIOError(return SQLITE_IOERR_TRUNCATE); 715 SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); 716 SetEndOfFile(pFile->h); 717 return SQLITE_OK; 718 } 719 720 #ifdef SQLITE_TEST 721 /* 722 ** Count the number of fullsyncs and normal syncs. This is used to test 723 ** that syncs and fullsyncs are occuring at the right times. 724 */ 725 int sqlite3_sync_count = 0; 726 int sqlite3_fullsync_count = 0; 727 #endif 728 729 /* 730 ** Make sure all writes to a particular file are committed to disk. 731 */ 732 static int winSync(sqlite3_file *id, int flags){ 733 winFile *pFile = (winFile*)id; 734 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype); 735 #ifdef SQLITE_TEST 736 if( flags & SQLITE_SYNC_FULL ){ 737 sqlite3_fullsync_count++; 738 } 739 sqlite3_sync_count++; 740 #endif 741 if( FlushFileBuffers(pFile->h) ){ 742 return SQLITE_OK; 743 }else{ 744 return SQLITE_IOERR; 745 } 746 } 747 748 /* 749 ** Determine the current size of a file in bytes 750 */ 751 static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ 752 winFile *pFile = (winFile*)id; 753 DWORD upperBits, lowerBits; 754 SimulateIOError(return SQLITE_IOERR_FSTAT); 755 lowerBits = GetFileSize(pFile->h, &upperBits); 756 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; 757 return SQLITE_OK; 758 } 759 760 /* 761 ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. 762 */ 763 #ifndef LOCKFILE_FAIL_IMMEDIATELY 764 # define LOCKFILE_FAIL_IMMEDIATELY 1 765 #endif 766 767 /* 768 ** Acquire a reader lock. 769 ** Different API routines are called depending on whether or not this 770 ** is Win95 or WinNT. 771 */ 772 static int getReadLock(winFile *pFile){ 773 int res; 774 if( isNT() ){ 775 OVERLAPPED ovlp; 776 ovlp.Offset = SHARED_FIRST; 777 ovlp.OffsetHigh = 0; 778 ovlp.hEvent = 0; 779 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, 780 0, SHARED_SIZE, 0, &ovlp); 781 }else{ 782 int lk; 783 sqlite3_randomness(sizeof(lk), &lk); 784 pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); 785 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); 786 } 787 return res; 788 } 789 790 /* 791 ** Undo a readlock 792 */ 793 static int unlockReadLock(winFile *pFile){ 794 int res; 795 if( isNT() ){ 796 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 797 }else{ 798 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); 799 } 800 return res; 801 } 802 803 /* 804 ** Lock the file with the lock specified by parameter locktype - one 805 ** of the following: 806 ** 807 ** (1) SHARED_LOCK 808 ** (2) RESERVED_LOCK 809 ** (3) PENDING_LOCK 810 ** (4) EXCLUSIVE_LOCK 811 ** 812 ** Sometimes when requesting one lock state, additional lock states 813 ** are inserted in between. The locking might fail on one of the later 814 ** transitions leaving the lock state different from what it started but 815 ** still short of its goal. The following chart shows the allowed 816 ** transitions and the inserted intermediate states: 817 ** 818 ** UNLOCKED -> SHARED 819 ** SHARED -> RESERVED 820 ** SHARED -> (PENDING) -> EXCLUSIVE 821 ** RESERVED -> (PENDING) -> EXCLUSIVE 822 ** PENDING -> EXCLUSIVE 823 ** 824 ** This routine will only increase a lock. The winUnlock() routine 825 ** erases all locks at once and returns us immediately to locking level 0. 826 ** It is not possible to lower the locking level one step at a time. You 827 ** must go straight to locking level 0. 828 */ 829 static int winLock(sqlite3_file *id, int locktype){ 830 int rc = SQLITE_OK; /* Return code from subroutines */ 831 int res = 1; /* Result of a windows lock call */ 832 int newLocktype; /* Set pFile->locktype to this value before exiting */ 833 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ 834 winFile *pFile = (winFile*)id; 835 836 assert( pFile!=0 ); 837 OSTRACE5("LOCK %d %d was %d(%d)\n", 838 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); 839 840 /* If there is already a lock of this type or more restrictive on the 841 ** OsFile, do nothing. Don't use the end_lock: exit path, as 842 ** sqlite3OsEnterMutex() hasn't been called yet. 843 */ 844 if( pFile->locktype>=locktype ){ 845 return SQLITE_OK; 846 } 847 848 /* Make sure the locking sequence is correct 849 */ 850 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); 851 assert( locktype!=PENDING_LOCK ); 852 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); 853 854 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or 855 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of 856 ** the PENDING_LOCK byte is temporary. 857 */ 858 newLocktype = pFile->locktype; 859 if( pFile->locktype==NO_LOCK 860 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) 861 ){ 862 int cnt = 3; 863 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ 864 /* Try 3 times to get the pending lock. The pending lock might be 865 ** held by another reader process who will release it momentarily. 866 */ 867 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); 868 Sleep(1); 869 } 870 gotPendingLock = res; 871 } 872 873 /* Acquire a shared lock 874 */ 875 if( locktype==SHARED_LOCK && res ){ 876 assert( pFile->locktype==NO_LOCK ); 877 res = getReadLock(pFile); 878 if( res ){ 879 newLocktype = SHARED_LOCK; 880 } 881 } 882 883 /* Acquire a RESERVED lock 884 */ 885 if( locktype==RESERVED_LOCK && res ){ 886 assert( pFile->locktype==SHARED_LOCK ); 887 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 888 if( res ){ 889 newLocktype = RESERVED_LOCK; 890 } 891 } 892 893 /* Acquire a PENDING lock 894 */ 895 if( locktype==EXCLUSIVE_LOCK && res ){ 896 newLocktype = PENDING_LOCK; 897 gotPendingLock = 0; 898 } 899 900 /* Acquire an EXCLUSIVE lock 901 */ 902 if( locktype==EXCLUSIVE_LOCK && res ){ 903 assert( pFile->locktype>=SHARED_LOCK ); 904 res = unlockReadLock(pFile); 905 OSTRACE2("unreadlock = %d\n", res); 906 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 907 if( res ){ 908 newLocktype = EXCLUSIVE_LOCK; 909 }else{ 910 OSTRACE2("error-code = %d\n", GetLastError()); 911 getReadLock(pFile); 912 } 913 } 914 915 /* If we are holding a PENDING lock that ought to be released, then 916 ** release it now. 917 */ 918 if( gotPendingLock && locktype==SHARED_LOCK ){ 919 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); 920 } 921 922 /* Update the state of the lock has held in the file descriptor then 923 ** return the appropriate result code. 924 */ 925 if( res ){ 926 rc = SQLITE_OK; 927 }else{ 928 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h, 929 locktype, newLocktype); 930 rc = SQLITE_BUSY; 931 } 932 pFile->locktype = newLocktype; 933 return rc; 934 } 935 936 /* 937 ** This routine checks if there is a RESERVED lock held on the specified 938 ** file by this or any other process. If such a lock is held, return 939 ** non-zero, otherwise zero. 940 */ 941 static int winCheckReservedLock(sqlite3_file *id){ 942 int rc; 943 winFile *pFile = (winFile*)id; 944 assert( pFile!=0 ); 945 if( pFile->locktype>=RESERVED_LOCK ){ 946 rc = 1; 947 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); 948 }else{ 949 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 950 if( rc ){ 951 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 952 } 953 rc = !rc; 954 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc); 955 } 956 return rc; 957 } 958 959 /* 960 ** Lower the locking level on file descriptor id to locktype. locktype 961 ** must be either NO_LOCK or SHARED_LOCK. 962 ** 963 ** If the locking level of the file descriptor is already at or below 964 ** the requested locking level, this routine is a no-op. 965 ** 966 ** It is not possible for this routine to fail if the second argument 967 ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine 968 ** might return SQLITE_IOERR; 969 */ 970 static int winUnlock(sqlite3_file *id, int locktype){ 971 int type; 972 winFile *pFile = (winFile*)id; 973 int rc = SQLITE_OK; 974 assert( pFile!=0 ); 975 assert( locktype<=SHARED_LOCK ); 976 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, 977 pFile->locktype, pFile->sharedLockByte); 978 type = pFile->locktype; 979 if( type>=EXCLUSIVE_LOCK ){ 980 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); 981 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ 982 /* This should never happen. We should always be able to 983 ** reacquire the read lock */ 984 rc = SQLITE_IOERR_UNLOCK; 985 } 986 } 987 if( type>=RESERVED_LOCK ){ 988 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); 989 } 990 if( locktype==NO_LOCK && type>=SHARED_LOCK ){ 991 unlockReadLock(pFile); 992 } 993 if( type>=PENDING_LOCK ){ 994 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); 995 } 996 pFile->locktype = locktype; 997 return rc; 998 } 999 1000 /* 1001 ** Control and query of the open file handle. 1002 */ 1003 static int winFileControl(sqlite3_file *id, int op, void *pArg){ 1004 switch( op ){ 1005 case SQLITE_FCNTL_LOCKSTATE: { 1006 *(int*)pArg = ((winFile*)id)->locktype; 1007 return SQLITE_OK; 1008 } 1009 } 1010 return SQLITE_ERROR; 1011 } 1012 1013 /* 1014 ** Return the sector size in bytes of the underlying block device for 1015 ** the specified file. This is almost always 512 bytes, but may be 1016 ** larger for some devices. 1017 ** 1018 ** SQLite code assumes this function cannot fail. It also assumes that 1019 ** if two files are created in the same file-system directory (i.e. 1020 ** a database and its journal file) that the sector size will be the 1021 ** same for both. 1022 */ 1023 static int winSectorSize(sqlite3_file *id){ 1024 return SQLITE_DEFAULT_SECTOR_SIZE; 1025 } 1026 1027 /* 1028 ** Return a vector of device characteristics. 1029 */ 1030 static int winDeviceCharacteristics(sqlite3_file *id){ 1031 return 0; 1032 } 1033 1034 /* 1035 ** This vector defines all the methods that can operate on an 1036 ** sqlite3_file for win32. 1037 */ 1038 static const sqlite3_io_methods winIoMethod = { 1039 1, /* iVersion */ 1040 winClose, 1041 winRead, 1042 winWrite, 1043 winTruncate, 1044 winSync, 1045 winFileSize, 1046 winLock, 1047 winUnlock, 1048 winCheckReservedLock, 1049 winFileControl, 1050 winSectorSize, 1051 winDeviceCharacteristics 1052 }; 1053 1054 /*************************************************************************** 1055 ** Here ends the I/O methods that form the sqlite3_io_methods object. 1056 ** 1057 ** The next block of code implements the VFS methods. 1058 ****************************************************************************/ 1059 1060 /* 1061 ** Convert a UTF-8 filename into whatever form the underlying 1062 ** operating system wants filenames in. Space to hold the result 1063 ** is obtained from malloc and must be freed by the calling 1064 ** function. 1065 */ 1066 static void *convertUtf8Filename(const char *zFilename){ 1067 void *zConverted = 0; 1068 if( isNT() ){ 1069 zConverted = utf8ToUnicode(zFilename); 1070 }else{ 1071 zConverted = utf8ToMbcs(zFilename); 1072 } 1073 /* caller will handle out of memory */ 1074 return zConverted; 1075 } 1076 1077 /* 1078 ** Open a file. 1079 */ 1080 static int winOpen( 1081 sqlite3_vfs *pVfs, /* Not used */ 1082 const char *zName, /* Name of the file (UTF-8) */ 1083 sqlite3_file *id, /* Write the SQLite file handle here */ 1084 int flags, /* Open mode flags */ 1085 int *pOutFlags /* Status return flags */ 1086 ){ 1087 HANDLE h; 1088 DWORD dwDesiredAccess; 1089 DWORD dwShareMode; 1090 DWORD dwCreationDisposition; 1091 DWORD dwFlagsAndAttributes = 0; 1092 int isTemp; 1093 winFile *pFile = (winFile*)id; 1094 void *zConverted = convertUtf8Filename(zName); 1095 if( zConverted==0 ){ 1096 return SQLITE_NOMEM; 1097 } 1098 1099 if( flags & SQLITE_OPEN_READWRITE ){ 1100 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 1101 }else{ 1102 dwDesiredAccess = GENERIC_READ; 1103 } 1104 if( flags & SQLITE_OPEN_CREATE ){ 1105 dwCreationDisposition = OPEN_ALWAYS; 1106 }else{ 1107 dwCreationDisposition = OPEN_EXISTING; 1108 } 1109 if( flags & SQLITE_OPEN_MAIN_DB ){ 1110 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 1111 }else{ 1112 dwShareMode = 0; 1113 } 1114 if( flags & SQLITE_OPEN_DELETEONCLOSE ){ 1115 #if OS_WINCE 1116 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; 1117 #else 1118 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY 1119 | FILE_ATTRIBUTE_HIDDEN 1120 | FILE_FLAG_DELETE_ON_CLOSE; 1121 #endif 1122 isTemp = 1; 1123 }else{ 1124 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 1125 isTemp = 0; 1126 } 1127 /* Reports from the internet are that performance is always 1128 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ 1129 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; 1130 if( isNT() ){ 1131 h = CreateFileW((WCHAR*)zConverted, 1132 dwDesiredAccess, 1133 dwShareMode, 1134 NULL, 1135 dwCreationDisposition, 1136 dwFlagsAndAttributes, 1137 NULL 1138 ); 1139 }else{ 1140 #if OS_WINCE 1141 return SQLITE_NOMEM; 1142 #else 1143 h = CreateFileA((char*)zConverted, 1144 dwDesiredAccess, 1145 dwShareMode, 1146 NULL, 1147 dwCreationDisposition, 1148 dwFlagsAndAttributes, 1149 NULL 1150 ); 1151 #endif 1152 } 1153 if( h==INVALID_HANDLE_VALUE ){ 1154 free(zConverted); 1155 if( flags & SQLITE_OPEN_READWRITE ){ 1156 return winOpen(0, zName, id, 1157 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); 1158 }else{ 1159 return SQLITE_CANTOPEN; 1160 } 1161 } 1162 if( pOutFlags ){ 1163 if( flags & SQLITE_OPEN_READWRITE ){ 1164 *pOutFlags = SQLITE_OPEN_READWRITE; 1165 }else{ 1166 *pOutFlags = SQLITE_OPEN_READONLY; 1167 } 1168 } 1169 memset(pFile, 0, sizeof(*pFile)); 1170 pFile->pMethod = &winIoMethod; 1171 pFile->h = h; 1172 #if OS_WINCE 1173 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == 1174 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) 1175 && !winceCreateLock(zName, pFile) 1176 ){ 1177 CloseHandle(h); 1178 free(zConverted); 1179 return SQLITE_CANTOPEN; 1180 } 1181 if( isTemp ){ 1182 pFile->zDeleteOnClose = zConverted; 1183 }else 1184 #endif 1185 { 1186 free(zConverted); 1187 } 1188 OpenCounter(+1); 1189 return SQLITE_OK; 1190 } 1191 1192 /* 1193 ** Delete the named file. 1194 ** 1195 ** Note that windows does not allow a file to be deleted if some other 1196 ** process has it open. Sometimes a virus scanner or indexing program 1197 ** will open a journal file shortly after it is created in order to do 1198 ** whatever does. While this other process is holding the 1199 ** file open, we will be unable to delete it. To work around this 1200 ** problem, we delay 100 milliseconds and try to delete again. Up 1201 ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving 1202 ** up and returning an error. 1203 */ 1204 #define MX_DELETION_ATTEMPTS 5 1205 static int winDelete( 1206 sqlite3_vfs *pVfs, /* Not used on win32 */ 1207 const char *zFilename, /* Name of file to delete */ 1208 int syncDir /* Not used on win32 */ 1209 ){ 1210 int cnt = 0; 1211 int rc; 1212 void *zConverted = convertUtf8Filename(zFilename); 1213 if( zConverted==0 ){ 1214 return SQLITE_NOMEM; 1215 } 1216 SimulateIOError(return SQLITE_IOERR_DELETE); 1217 if( isNT() ){ 1218 do{ 1219 DeleteFileW(zConverted); 1220 }while( (rc = GetFileAttributesW(zConverted))!=0xffffffff 1221 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); 1222 }else{ 1223 #if OS_WINCE 1224 return SQLITE_NOMEM; 1225 #else 1226 do{ 1227 DeleteFileA(zConverted); 1228 }while( (rc = GetFileAttributesA(zConverted))!=0xffffffff 1229 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); 1230 #endif 1231 } 1232 free(zConverted); 1233 OSTRACE2("DELETE \"%s\"\n", zFilename); 1234 return rc==0xffffffff ? SQLITE_OK : SQLITE_IOERR_DELETE; 1235 } 1236 1237 /* 1238 ** Check the existance and status of a file. 1239 */ 1240 static int winAccess( 1241 sqlite3_vfs *pVfs, /* Not used on win32 */ 1242 const char *zFilename, /* Name of file to check */ 1243 int flags /* Type of test to make on this file */ 1244 ){ 1245 DWORD attr; 1246 int rc; 1247 void *zConverted = convertUtf8Filename(zFilename); 1248 if( zConverted==0 ){ 1249 return SQLITE_NOMEM; 1250 } 1251 if( isNT() ){ 1252 attr = GetFileAttributesW((WCHAR*)zConverted); 1253 }else{ 1254 #if OS_WINCE 1255 return SQLITE_NOMEM; 1256 #else 1257 attr = GetFileAttributesA((char*)zConverted); 1258 #endif 1259 } 1260 free(zConverted); 1261 switch( flags ){ 1262 case SQLITE_ACCESS_READ: 1263 case SQLITE_ACCESS_EXISTS: 1264 rc = attr!=0xffffffff; 1265 break; 1266 case SQLITE_ACCESS_READWRITE: 1267 rc = (attr & FILE_ATTRIBUTE_READONLY)==0; 1268 break; 1269 default: 1270 assert(!"Invalid flags argument"); 1271 } 1272 return rc; 1273 } 1274 1275 1276 /* 1277 ** Create a temporary file name in zBuf. zBuf must be big enough to 1278 ** hold at pVfs->mxPathname characters. 1279 */ 1280 static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 1281 static char zChars[] = 1282 "abcdefghijklmnopqrstuvwxyz" 1283 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1284 "0123456789"; 1285 int i, j; 1286 char zTempPath[MAX_PATH+1]; 1287 if( sqlite3_temp_directory ){ 1288 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); 1289 }else if( isNT() ){ 1290 char *zMulti; 1291 WCHAR zWidePath[MAX_PATH]; 1292 GetTempPathW(MAX_PATH-30, zWidePath); 1293 zMulti = unicodeToUtf8(zWidePath); 1294 if( zMulti ){ 1295 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); 1296 free(zMulti); 1297 }else{ 1298 return SQLITE_NOMEM; 1299 } 1300 }else{ 1301 char *zUtf8; 1302 char zMbcsPath[MAX_PATH]; 1303 GetTempPathA(MAX_PATH-30, zMbcsPath); 1304 zUtf8 = mbcsToUtf8(zMbcsPath); 1305 if( zUtf8 ){ 1306 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); 1307 free(zUtf8); 1308 }else{ 1309 return SQLITE_NOMEM; 1310 } 1311 } 1312 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} 1313 zTempPath[i] = 0; 1314 sqlite3_snprintf(nBuf-30, zBuf, 1315 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); 1316 j = strlen(zBuf); 1317 sqlite3_randomness(20, &zBuf[j]); 1318 for(i=0; i<20; i++, j++){ 1319 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; 1320 } 1321 zBuf[j] = 0; 1322 OSTRACE2("TEMP FILENAME: %s\n", zBuf); 1323 return SQLITE_OK; 1324 } 1325 1326 /* 1327 ** Turn a relative pathname into a full pathname. Write the full 1328 ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname 1329 ** bytes in size. 1330 */ 1331 static int winFullPathname( 1332 sqlite3_vfs *pVfs, /* Pointer to vfs object */ 1333 const char *zRelative, /* Possibly relative input path */ 1334 int nFull, /* Size of output buffer in bytes */ 1335 char *zFull /* Output buffer */ 1336 ){ 1337 1338 #if defined(__CYGWIN__) 1339 cygwin_conv_to_full_win32_path(zRelative, zFull); 1340 return SQLITE_OK; 1341 #endif 1342 1343 #if OS_WINCE 1344 /* WinCE has no concept of a relative pathname, or so I am told. */ 1345 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); 1346 return SQLITE_OK; 1347 #endif 1348 1349 #if !OS_WINCE && !defined(__CYGWIN__) 1350 int nByte; 1351 void *zConverted; 1352 char *zOut; 1353 zConverted = convertUtf8Filename(zRelative); 1354 if( isNT() ){ 1355 WCHAR *zTemp; 1356 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; 1357 zTemp = malloc( nByte*sizeof(zTemp[0]) ); 1358 if( zTemp==0 ){ 1359 free(zConverted); 1360 return SQLITE_NOMEM; 1361 } 1362 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); 1363 free(zConverted); 1364 zOut = unicodeToUtf8(zTemp); 1365 free(zTemp); 1366 }else{ 1367 char *zTemp; 1368 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; 1369 zTemp = malloc( nByte*sizeof(zTemp[0]) ); 1370 if( zTemp==0 ){ 1371 free(zConverted); 1372 return SQLITE_NOMEM; 1373 } 1374 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); 1375 free(zConverted); 1376 zOut = mbcsToUtf8(zTemp); 1377 free(zTemp); 1378 } 1379 if( zOut ){ 1380 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); 1381 free(zOut); 1382 return SQLITE_OK; 1383 }else{ 1384 return SQLITE_NOMEM; 1385 } 1386 #endif 1387 } 1388 1389 #ifndef SQLITE_OMIT_LOAD_EXTENSION 1390 /* 1391 ** Interfaces for opening a shared library, finding entry points 1392 ** within the shared library, and closing the shared library. 1393 */ 1394 /* 1395 ** Interfaces for opening a shared library, finding entry points 1396 ** within the shared library, and closing the shared library. 1397 */ 1398 static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ 1399 HANDLE h; 1400 void *zConverted = convertUtf8Filename(zFilename); 1401 if( zConverted==0 ){ 1402 return 0; 1403 } 1404 if( isNT() ){ 1405 h = LoadLibraryW((WCHAR*)zConverted); 1406 }else{ 1407 #if OS_WINCE 1408 return 0; 1409 #else 1410 h = LoadLibraryA((char*)zConverted); 1411 #endif 1412 } 1413 free(zConverted); 1414 return (void*)h; 1415 } 1416 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ 1417 #if OS_WINCE 1418 int error = GetLastError(); 1419 if( error>0x7FFFFFF ){ 1420 sqlite3_snprintf(nBuf, zBufOut, "OsError 0x%x", error); 1421 }else{ 1422 sqlite3_snprintf(nBuf, zBufOut, "OsError %d", error); 1423 } 1424 #else 1425 FormatMessageA( 1426 FORMAT_MESSAGE_FROM_SYSTEM, 1427 NULL, 1428 GetLastError(), 1429 0, 1430 zBufOut, 1431 nBuf-1, 1432 0 1433 ); 1434 #endif 1435 } 1436 void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ 1437 #if OS_WINCE 1438 /* The GetProcAddressA() routine is only available on wince. */ 1439 return GetProcAddressA((HANDLE)pHandle, zSymbol); 1440 #else 1441 /* All other windows platforms expect GetProcAddress() to take 1442 ** an Ansi string regardless of the _UNICODE setting */ 1443 return GetProcAddress((HANDLE)pHandle, zSymbol); 1444 #endif 1445 } 1446 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ 1447 FreeLibrary((HANDLE)pHandle); 1448 } 1449 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ 1450 #define winDlOpen 0 1451 #define winDlError 0 1452 #define winDlSym 0 1453 #define winDlClose 0 1454 #endif 1455 1456 1457 /* 1458 ** Write up to nBuf bytes of randomness into zBuf. 1459 */ 1460 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ 1461 int n = 0; 1462 if( sizeof(SYSTEMTIME)<=nBuf-n ){ 1463 SYSTEMTIME x; 1464 GetSystemTime(&x); 1465 memcpy(&zBuf[n], &x, sizeof(x)); 1466 n += sizeof(x); 1467 } 1468 if( sizeof(DWORD)<=nBuf-n ){ 1469 DWORD pid = GetCurrentProcessId(); 1470 memcpy(&zBuf[n], &pid, sizeof(pid)); 1471 n += sizeof(pid); 1472 } 1473 if( sizeof(DWORD)<=nBuf-n ){ 1474 DWORD cnt = GetTickCount(); 1475 memcpy(&zBuf[n], &cnt, sizeof(cnt)); 1476 n += sizeof(cnt); 1477 } 1478 if( sizeof(LARGE_INTEGER)<=nBuf-n ){ 1479 LARGE_INTEGER i; 1480 QueryPerformanceCounter(&i); 1481 memcpy(&zBuf[n], &i, sizeof(i)); 1482 n += sizeof(i); 1483 } 1484 return n; 1485 } 1486 1487 1488 /* 1489 ** Sleep for a little while. Return the amount of time slept. 1490 */ 1491 static int winSleep(sqlite3_vfs *pVfs, int microsec){ 1492 Sleep((microsec+999)/1000); 1493 return ((microsec+999)/1000)*1000; 1494 } 1495 1496 /* 1497 ** The following variable, if set to a non-zero value, becomes the result 1498 ** returned from sqlite3OsCurrentTime(). This is used for testing. 1499 */ 1500 #ifdef SQLITE_TEST 1501 int sqlite3_current_time = 0; 1502 #endif 1503 1504 /* 1505 ** Find the current time (in Universal Coordinated Time). Write the 1506 ** current time and date as a Julian Day number into *prNow and 1507 ** return 0. Return 1 if the time and date cannot be found. 1508 */ 1509 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ 1510 FILETIME ft; 1511 /* FILETIME structure is a 64-bit value representing the number of 1512 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 1513 */ 1514 double now; 1515 #if OS_WINCE 1516 SYSTEMTIME time; 1517 GetSystemTime(&time); 1518 SystemTimeToFileTime(&time,&ft); 1519 #else 1520 GetSystemTimeAsFileTime( &ft ); 1521 #endif 1522 now = ((double)ft.dwHighDateTime) * 4294967296.0; 1523 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5; 1524 #ifdef SQLITE_TEST 1525 if( sqlite3_current_time ){ 1526 *prNow = sqlite3_current_time/86400.0 + 2440587.5; 1527 } 1528 #endif 1529 return 0; 1530 } 1531 1532 1533 /* 1534 ** Return a pointer to the sqlite3DefaultVfs structure. We use 1535 ** a function rather than give the structure global scope because 1536 ** some compilers (MSVC) do not allow forward declarations of 1537 ** initialized structures. 1538 */ 1539 sqlite3_vfs *sqlite3OsDefaultVfs(void){ 1540 static sqlite3_vfs winVfs = { 1541 1, /* iVersion */ 1542 sizeof(winFile), /* szOsFile */ 1543 MAX_PATH, /* mxPathname */ 1544 0, /* pNext */ 1545 "win32", /* zName */ 1546 0, /* pAppData */ 1547 1548 winOpen, /* xOpen */ 1549 winDelete, /* xDelete */ 1550 winAccess, /* xAccess */ 1551 winGetTempname, /* xGetTempName */ 1552 winFullPathname, /* xFullPathname */ 1553 winDlOpen, /* xDlOpen */ 1554 winDlError, /* xDlError */ 1555 winDlSym, /* xDlSym */ 1556 winDlClose, /* xDlClose */ 1557 winRandomness, /* xRandomness */ 1558 winSleep, /* xSleep */ 1559 winCurrentTime /* xCurrentTime */ 1560 }; 1561 1562 return &winVfs; 1563 } 1564 1565 #endif /* OS_WIN */ 1566