diff options
Diffstat (limited to 'src/Platform/Unix/File.cpp')
-rw-r--r-- | src/Platform/Unix/File.cpp | 11 |
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; |