VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Platform/Unix/File.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Platform/Unix/File.cpp')
-rw-r--r--src/Platform/Unix/File.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/Platform/Unix/File.cpp b/src/Platform/Unix/File.cpp
index d3413800..207efb4e 100644
--- a/src/Platform/Unix/File.cpp
+++ b/src/Platform/Unix/File.cpp
@@ -195,60 +195,71 @@ namespace VeraCrypt
#else
throw NotImplemented (SRC_POS);
#endif
}
uint64 File::Length () const
{
if_debug (ValidateState());
// BSD does not support seeking to the end of a device
#ifdef TC_BSD
if (Path.IsBlockDevice() || Path.IsCharacterDevice())
{
# ifdef TC_MACOSX
uint32 blockSize;
uint64 blockCount;
throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path));
return blockCount * blockSize;
# elif TC_OPENBSD
struct disklabel dl;
throw_sys_sub_if (ioctl (FileHandle, DIOCGPDINFO, &dl) == -1, wstring (Path));
return DL_GETDSIZE(&dl);
# else
uint64 mediaSize;
throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path));
return mediaSize;
# endif
}
#endif
+#ifdef TC_LINUX
+ // On Linux, try to use BLKGETSIZE64 for devices
+ if (Path.IsDevice())
+ {
+ uint64 mediaSize;
+ if (ioctl (FileHandle, BLKGETSIZE64, &mediaSize) != -1)
+ {
+ return mediaSize;
+ }
+ }
+#endif
off_t current = lseek (FileHandle, 0, SEEK_CUR);
throw_sys_sub_if (current == -1, wstring (Path));
SeekEnd (0);
uint64 length = lseek (FileHandle, 0, SEEK_CUR);
SeekAt (current);
return length;
}
void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags)
{
#ifdef TC_LINUX
int sysFlags = O_LARGEFILE;
#else
int sysFlags = 0;
#endif
switch (mode)
{
case CreateReadWrite:
sysFlags |= O_CREAT | O_TRUNC | O_RDWR;
break;
case CreateWrite:
sysFlags |= O_CREAT | O_TRUNC | O_WRONLY;
break;
case OpenRead:
sysFlags |= O_RDONLY;
break;