Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add runtime version checking for winSectorSize. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | winSectorSize |
Files: | files | file ages | folders |
SHA1: |
cb9d1ab33d4109e0712d1a9dd2e51861 |
User & Date: | mistachkin 2017-01-18 01:11:03.600 |
Context
2017-01-18
| ||
19:06 | Minimize the requested permissions when opening the volume on Windows 7 and Vista. (check-in: 8d429a59cd user: mistachkin tags: winSectorSize) | |
01:11 | Add runtime version checking for winSectorSize. (check-in: cb9d1ab33d user: mistachkin tags: winSectorSize) | |
00:27 | When determining sector sizes on Windows 7 and Vista, make sure the target file is on the same volume as corresponding root directory. (check-in: de699ead5a user: mistachkin tags: winSectorSize) | |
Changes
Changes to src/os_win.c.
︙ | ︙ | |||
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; #else static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; #endif #ifndef SYSCALL # define SYSCALL sqlite3_syscall_ptr #endif /* | > > > > | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; LONG SQLITE_WIN32_VOLATILE sqlite3_os_major = 0; LONG SQLITE_WIN32_VOLATILE sqlite3_os_minor = 0; #else static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; static LONG SQLITE_WIN32_VOLATILE sqlite3_os_major = 0; static LONG SQLITE_WIN32_VOLATILE sqlite3_os_minor = 0; #endif #ifndef SYSCALL # define SYSCALL sqlite3_syscall_ptr #endif /* |
︙ | ︙ | |||
1139 1140 1141 1142 1143 1144 1145 | #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) | > | > | > | | 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 | #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && defined(_WIN32_WINNT) && \ _WIN32_WINNT >= _WIN32_WINNT_VISTA { "DeviceIoControl", (SYSCALL)DeviceIoControl, 0 }, #else { "DeviceIoControl", (SYSCALL)0, 0 }, #endif #define osDeviceIoControl ((BOOL(WINAPI*)( \ HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPVOID, \ LPOVERLAPPED))aSyscall[80].pCurrent) #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && defined(_WIN32_WINNT) && \ _WIN32_WINNT >= _WIN32_WINNT_VISTA { "GetVolumeInformationByHandleW", (SYSCALL)GetVolumeInformationByHandleW, 0 }, #else { "GetVolumeInformationByHandleW", (SYSCALL)0, 0 }, #endif #define osGetVolumeInformationByHandleW ((BOOL(WINAPI*)( \ HANDLE,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR, \ DWORD))aSyscall[81].pCurrent) #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && defined(_WIN32_WINNT) && \ _WIN32_WINNT >= _WIN32_WINNT_VISTA { "GetVolumeInformationW", (SYSCALL)GetVolumeInformationW, 0 }, #else { "GetVolumeInformationW", (SYSCALL)0, 0 }, #endif #define osGetVolumeInformationW ((BOOL(WINAPI*)( \ LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR, \ |
︙ | ︙ | |||
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | # define osIsNT() (1) #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) #else # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ int sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT ** kernel. */ return 1; #elif SQLITE_WIN32_GETVERSIONEX | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < | < < < < < < < < < < | 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 | # define osIsNT() (1) #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) #else # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This following version checking macros should evaluate to non-zero only ** when running on Windows Vista (or higher) or Windows 8 (or higher). */ #if !SQLITE_WIN32_GETVERSIONEX # define osIsVistaPlus() (1) # define osIsWin8Plus() (1) #elif SQLITE_OS_WINCE # define osIsVistaPlus() (0) # define osIsWin8Plus() (0) #elif SQLITE_OS_WINRT # define osIsVistaPlus() (1) # define osIsWin8Plus() (1) #else # define osIsVistaPlus() (winGetVersionEx() && ((sqlite3_os_major>6) || \ ((sqlite3_os_major==6) && (sqlite3_os_minor>=0)))) # define osIsWin8Plus() (winGetVersionEx() && ((sqlite3_os_major>6) || \ ((sqlite3_os_major==6) && (sqlite3_os_minor>=2)))) #endif /* ** This function populates the Windows version information needed by this ** module. Use of the GetVersionExA or GetVersionExW function is required. ** The return value will be non-zero if version information was queried. */ #if SQLITE_WIN32_GETVERSIONEX static int winGetVersionEx(){ if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ #if defined(SQLITE_WIN32_HAS_ANSI) OSVERSIONINFOA sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExA(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); osInterlockedCompareExchange(&sqlite3_os_major, (LONG)sInfo.dwMajorVersion, 0); osInterlockedCompareExchange(&sqlite3_os_minor, (LONG)sInfo.dwMinorVersion, 0); return 1; #elif defined(SQLITE_WIN32_HAS_WIDE) OSVERSIONINFOW sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExW(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); osInterlockedCompareExchange(&sqlite3_os_major, (LONG)sInfo.dwMajorVersion, 0); osInterlockedCompareExchange(&sqlite3_os_minor, (LONG)sInfo.dwMinorVersion, 0); return 1; #endif } return 0; } #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ int sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT ** kernel. */ return 1; #elif SQLITE_WIN32_GETVERSIONEX winGetVersionEx(); return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #elif SQLITE_TEST return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #else /* ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are ** deprecated are always assumed to be based on the NT kernel. |
︙ | ︙ | |||
3573 3574 3575 3576 3577 3578 3579 | } #endif } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; } | > | | 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 | } #endif } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; } #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && \ defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA /* ** This function attempts to determine if the specified file resides on the ** same volume as the corresponding root directory. If not, the specified ** file may be impacted by a hard link, symbolic link, or reparse point (e.g. ** junction). ** ** This function may return false even when the file is on the same volume |
︙ | ︙ | |||
3616 3617 3618 3619 3620 3621 3622 | ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and its journal file) that the sector size will be the ** same for both. */ static int winSectorSize(sqlite3_file *id){ #if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN8 | > | | | | | | | | | | | | | | | > > > > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | > < | 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 | ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and its journal file) that the sector size will be the ** same for both. */ static int winSectorSize(sqlite3_file *id){ #if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN8 if( osIsWin8Plus() ){ winFile *pFile = (winFile*)id; FILE_STORAGE_INFO info; memset(&info, 0, sizeof(FILE_STORAGE_INFO)); if( osGetFileInformationByHandleEx(pFile->h, FileStorageInfo, &info, sizeof(info)) ){ ULONG size = info.FileSystemEffectivePhysicalBytesPerSectorForAtomicity; OSTRACE(("SECTOR file=%p, size=%lu\n", pFile->h, size)); if( size>0 && size<=2147483647 ){ return (int)size; } }else{ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winSectorSize1", pFile->zPath); } } #endif #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && \ defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA if( osIsVistaPlus() ){ winFile *pFile = (winFile*)id; if( winIsDriveLetterAndColon(pFile->zPath) && winIsOnSameVolume(pFile) ){ WCHAR zDisk[] = L"\\\\.\\_:\0"; /* underscore will be drive letter */ HANDLE hDisk; zDisk[4] = (WCHAR)pFile->zPath[0]; /* 'A' to 'Z' only, upper/lower case */ assert( (zDisk[4]>=L'A' && zDisk[4]<=L'Z') || (zDisk[4]>=L'a' && zDisk[4]<=L'z') ); hDisk = osCreateFileW(zDisk, STANDARD_RIGHTS_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( hDisk!=NULL ){ STORAGE_PROPERTY_QUERY query; STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignment; DWORD bytes = 0; memset(&query, 0, sizeof(STORAGE_PROPERTY_QUERY)); memset(&alignment, 0, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR)); query.QueryType = PropertyStandardQuery; query.PropertyId = StorageAccessAlignmentProperty; if( osDeviceIoControl(hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(STORAGE_PROPERTY_QUERY), &alignment, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), &bytes, NULL) ){ DWORD size = alignment.BytesPerPhysicalSector; OSTRACE(("SECTOR file=%p, size=%lu\n", pFile->h, size)); if( size>0 && size<=2147483647 ){ return (int)size; } }else{ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winSectorSize2", pFile->zPath); } osCloseHandle(hDisk); }else{ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winSectorSize3", pFile->zPath); } } } #endif (void)id; return SQLITE_DEFAULT_SECTOR_SIZE; } /* ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ |
︙ | ︙ |