/ Check-in [de699ead]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When determining sector sizes on Windows 7 and Vista, make sure the target file is on the same volume as corresponding root directory.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | winSectorSize
Files: files | file ages | folders
SHA1:de699ead5a8c5bcf074ef220365fe4a1e5310de4
User & Date: mistachkin 2017-01-18 00:27:09
Context
2017-01-18
01:11
Add runtime version checking for winSectorSize. check-in: cb9d1ab3 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: de699ead user: mistachkin tags: winSectorSize
2017-01-13
22:21
Merge updates from trunk. check-in: 8b42b8e3 user: mistachkin tags: winSectorSize
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_win.c.

1148
1149
1150
1151
1152
1153
1154




















1155
1156
1157
1158
1159
1160
1161
....
3553
3554
3555
3556
3557
3558
3559































3560
3561
3562
3563
3564
3565
3566
....
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
....
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
#else
  { "DeviceIoControl",          (SYSCALL)0,                      0 },
#endif

#define osDeviceIoControl ((BOOL(WINAPI*)( \
        HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPVOID, \
        LPOVERLAPPED))aSyscall[80].pCurrent)





















}; /* End of the overrideable system calls */

/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
................................................................................
    }
#endif
  }
  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  return SQLITE_NOTFOUND;
}
































/*
** Return the sector size in bytes of the underlying block device for
** the specified file. This is almost always 512 bytes, but may be
** larger for some devices.
**
** SQLite code assumes this function cannot fail. It also assumes that
** if two files are created in the same file-system directory (i.e.
................................................................................
  }else{
    pFile->lastErrno = osGetLastError();
    winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
                     "winSectorSize1", pFile->zPath);
  }
#elif defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
  winFile *pFile = (winFile*)id;
  if( winIsDriveLetterAndColon(pFile->zPath) ){
    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,
................................................................................
    winGetSystemCall,      /* xGetSystemCall */
    winNextSystemCall,     /* xNextSystemCall */
  };
#endif

  /* Double-check that the aSyscall[] array has been constructed
  ** correctly.  See ticket [bb3a86e890c8e96ab] */
  assert( ArraySize(aSyscall)==81 );

  /* get memory map allocation granularity */
  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
  osGetNativeSystemInfo(&winSysInfo);
#else
  osGetSystemInfo(&winSysInfo);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







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
1181
....
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
....
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
....
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
#else
  { "DeviceIoControl",          (SYSCALL)0,                      0 },
#endif

#define osDeviceIoControl ((BOOL(WINAPI*)( \
        HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPVOID, \
        LPOVERLAPPED))aSyscall[80].pCurrent)

#if 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(_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, \
        DWORD))aSyscall[82].pCurrent)

}; /* End of the overrideable system calls */

/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
................................................................................
    }
#endif
  }
  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
  return SQLITE_NOTFOUND;
}

#if 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
** as the corresponding root directory.  This function may return true only
** when there is no doubt that the specified file is on the same volume as
** the corresponding root directory associated with the volume.
*/
static BOOL winIsOnSameVolume(winFile *pFile){
  WCHAR zRoot[] = L"_:\\\0"; /* underscore will be drive letter */
  DWORD dwFileVolumeSerialNumber = 0;
  DWORD dwRootVolumeSerialNumber = 0;

  if ( !osGetVolumeInformationByHandleW(pFile->h, NULL, 0,
                                        &dwFileVolumeSerialNumber, NULL,
                                        NULL, NULL, 0) ){
    return FALSE;
  }
  zRoot[0] = (WCHAR)pFile->zPath[0]; /* 'A' to 'Z' only, upper/lower case */
  if( !osGetVolumeInformationW(zRoot, NULL, 0, &dwRootVolumeSerialNumber,
                               NULL, NULL, NULL, 0) ){
    return FALSE;
  }
  return (dwFileVolumeSerialNumber == dwRootVolumeSerialNumber);
}
#endif

/*
** Return the sector size in bytes of the underlying block device for
** the specified file. This is almost always 512 bytes, but may be
** larger for some devices.
**
** SQLite code assumes this function cannot fail. It also assumes that
** if two files are created in the same file-system directory (i.e.
................................................................................
  }else{
    pFile->lastErrno = osGetLastError();
    winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
                     "winSectorSize1", pFile->zPath);
  }
#elif defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
  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,
................................................................................
    winGetSystemCall,      /* xGetSystemCall */
    winNextSystemCall,     /* xNextSystemCall */
  };
#endif

  /* Double-check that the aSyscall[] array has been constructed
  ** correctly.  See ticket [bb3a86e890c8e96ab] */
  assert( ArraySize(aSyscall)==83 );

  /* get memory map allocation granularity */
  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
  osGetNativeSystemInfo(&winSysInfo);
#else
  osGetSystemInfo(&winSysInfo);