"Fossies" - the Fresh Open Source Software Archive

Member "src/Platform/Unix/File.cpp" (10 Oct 2018, 8449 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "File.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2  Derived from source code of TrueCrypt 7.1a, which is
    3  Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
    4  by the TrueCrypt License 3.0.
    5 
    6  Modifications and additions to the original source code (contained in this file)
    7  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
    8  and are governed by the Apache License 2.0 the full text of which is
    9  contained in the file License.txt included in VeraCrypt binary and source
   10  code distribution packages.
   11 */
   12 
   13 #include <errno.h>
   14 #include <fcntl.h>
   15 #include <unistd.h>
   16 #include <utime.h>
   17 
   18 #ifdef TC_LINUX
   19 #include <sys/mount.h>
   20 #endif
   21 
   22 #ifdef TC_BSD
   23 #include <sys/disk.h>
   24 #endif
   25 
   26 #ifdef TC_SOLARIS
   27 #include <stropts.h>
   28 #include <sys/dkio.h>
   29 #endif
   30 
   31 #include <sys/file.h>
   32 #include <sys/types.h>
   33 #include <sys/stat.h>
   34 
   35 #include "Platform/File.h"
   36 #include "Platform/TextReader.h"
   37 
   38 namespace VeraCrypt
   39 {
   40 #if 0
   41 #   define TC_TRACE_FILE_OPERATIONS
   42 
   43     static void TraceFileOperation (int fileHandle, FilePath filePath, bool write, uint64 length, int64 position = -1)
   44     {
   45         string path = filePath;
   46         if (path.empty() || path.find ("veracrypt_aux_mnt") != string::npos)
   47             return;
   48 
   49         stringstream s;
   50         s << path << ": " << (write ? "W " : "R ") << (position == -1 ? lseek (fileHandle, 0, SEEK_CUR) : position) << " (" << length << ")";
   51         SystemLog::WriteError (s.str());
   52     }
   53 #endif
   54 
   55     void File::Close ()
   56     {
   57         if_debug (ValidateState());
   58 
   59         if (!SharedHandle)
   60         {
   61             close (FileHandle);
   62             FileIsOpen = false;
   63 
   64             if ((mFileOpenFlags & File::PreserveTimestamps) && Path.IsFile())
   65             {
   66                 struct utimbuf u;
   67                 u.actime = AccTime;
   68                 u.modtime = ModTime;
   69 
   70                 try
   71                 {
   72                     throw_sys_sub_if (utime (string (Path).c_str(), &u) == -1, wstring (Path));
   73                 }
   74                 catch (...) // Suppress errors to allow using read-only files
   75                 {
   76 #ifdef DEBUG
   77                     throw;
   78 #endif
   79                 }
   80             }
   81         }
   82     }
   83 
   84     void File::Delete ()
   85     {
   86         Close();
   87         Path.Delete();
   88     }
   89 
   90 
   91     void File::Flush () const
   92     {
   93         if_debug (ValidateState());
   94         throw_sys_sub_if (fsync (FileHandle) != 0, wstring (Path));
   95     }
   96 
   97     uint32 File::GetDeviceSectorSize () const
   98     {
   99         if (Path.IsDevice())
  100         {
  101 #ifdef TC_LINUX
  102             int blockSize;
  103             throw_sys_sub_if (ioctl (FileHandle, BLKSSZGET, &blockSize) == -1, wstring (Path));
  104             return blockSize;
  105 
  106 #elif defined (TC_MACOSX)
  107             uint32 blockSize;
  108             throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
  109             return blockSize;
  110 
  111 #elif defined (TC_FREEBSD)
  112             u_int sectorSize;
  113             throw_sys_sub_if (ioctl (FileHandle, DIOCGSECTORSIZE, &sectorSize) == -1, wstring (Path));
  114             return (uint32) sectorSize;
  115 
  116 #elif defined (TC_SOLARIS)
  117             struct dk_minfo mediaInfo;
  118             throw_sys_sub_if (ioctl (FileHandle, DKIOCGMEDIAINFO, &mediaInfo) == -1, wstring (Path));
  119             return mediaInfo.dki_lbsize;
  120 
  121 #else
  122 #   error GetDeviceSectorSize()
  123 #endif
  124         }
  125         else
  126             throw ParameterIncorrect (SRC_POS);
  127     }
  128 
  129     uint64 File::GetPartitionDeviceStartOffset () const
  130     {
  131 #ifdef TC_LINUX
  132 
  133         // HDIO_GETGEO ioctl is limited by the size of long
  134         TextReader tr ("/sys/block/" + string (Path.ToHostDriveOfPartition().ToBaseName()) + "/" + string (Path.ToBaseName()) + "/start");
  135 
  136         string line;
  137         tr.ReadLine (line);
  138         return StringConverter::ToUInt64 (line) * GetDeviceSectorSize();
  139 
  140 #elif defined (TC_MACOSX)
  141 
  142 #ifndef DKIOCGETBASE
  143 #   define DKIOCGETBASE _IOR('d', 73, uint64)
  144 #endif
  145         uint64 offset;
  146         throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBASE, &offset) == -1, wstring (Path));
  147         return offset;
  148 
  149 #elif defined (TC_SOLARIS)
  150 
  151         struct extpart_info partInfo;
  152         throw_sys_sub_if (ioctl (FileHandle, DKIOCEXTPARTINFO, &partInfo) == -1, wstring (Path));
  153         return partInfo.p_start * GetDeviceSectorSize();
  154 
  155 #else
  156         throw NotImplemented (SRC_POS);
  157 #endif
  158     }
  159 
  160     uint64 File::Length () const
  161     {
  162         if_debug (ValidateState());
  163 
  164         // BSD does not support seeking to the end of a device
  165 #ifdef TC_BSD
  166         if (Path.IsBlockDevice() || Path.IsCharacterDevice())
  167         {
  168 #   ifdef TC_MACOSX
  169             uint32 blockSize;
  170             uint64 blockCount;
  171             throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKSIZE, &blockSize) == -1, wstring (Path));
  172             throw_sys_sub_if (ioctl (FileHandle, DKIOCGETBLOCKCOUNT, &blockCount) == -1, wstring (Path));
  173             return blockCount * blockSize;
  174 #   else
  175             uint64 mediaSize;
  176             throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path));
  177             return mediaSize;
  178 #   endif
  179         }
  180 #endif
  181         off_t current = lseek (FileHandle, 0, SEEK_CUR);
  182         throw_sys_sub_if (current == -1, wstring (Path));
  183         SeekEnd (0);
  184         uint64 length = lseek (FileHandle, 0, SEEK_CUR);
  185         SeekAt (current);
  186         return length;
  187     }
  188 
  189     void File::Open (const FilePath &path, FileOpenMode mode, FileShareMode shareMode, FileOpenFlags flags)
  190     {
  191 #ifdef TC_LINUX
  192         int sysFlags = O_LARGEFILE;
  193 #else
  194         int sysFlags = 0;
  195 #endif
  196 
  197         switch (mode)
  198         {
  199         case CreateReadWrite:
  200             sysFlags |= O_CREAT | O_TRUNC | O_RDWR;
  201             break;
  202 
  203         case CreateWrite:
  204             sysFlags |= O_CREAT | O_TRUNC | O_WRONLY;
  205             break;
  206 
  207         case OpenRead:
  208             sysFlags |= O_RDONLY;
  209             break;
  210 
  211         case OpenWrite:
  212             sysFlags |= O_WRONLY;
  213             break;
  214 
  215         case OpenReadWrite:
  216             sysFlags |= O_RDWR;
  217             break;
  218 
  219         default:
  220             throw ParameterIncorrect (SRC_POS);
  221         }
  222 
  223         if ((flags & File::PreserveTimestamps) && path.IsFile())
  224         {
  225             struct stat statData;
  226             throw_sys_sub_if (stat (string (path).c_str(), &statData) == -1, wstring (path));
  227             AccTime = statData.st_atime;
  228             ModTime = statData.st_mtime;
  229         }
  230 
  231         FileHandle = open (string (path).c_str(), sysFlags, S_IRUSR | S_IWUSR);
  232         throw_sys_sub_if (FileHandle == -1, wstring (path));
  233 
  234 #if 0 // File locking is disabled to avoid remote filesystem locking issues
  235         try
  236         {
  237             struct flock fl;
  238             memset (&fl, 0, sizeof (fl));
  239             fl.l_whence = SEEK_SET;
  240             fl.l_start = 0;
  241             fl.l_len = 0;
  242 
  243             switch (shareMode)
  244             {
  245             case ShareNone:
  246                 fl.l_type = F_WRLCK;
  247                 if (fcntl (FileHandle, F_SETLK, &fl) == -1)
  248                     throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path));
  249                 break;
  250 
  251             case ShareRead:
  252                 fl.l_type = F_RDLCK;
  253                 if (fcntl (FileHandle, F_SETLK, &fl) == -1)
  254                     throw_sys_sub_if (errno == EAGAIN || errno == EACCES, wstring (path));
  255                 break;
  256 
  257             case ShareReadWrite:
  258                 fl.l_type = (mode == OpenRead ? F_RDLCK : F_WRLCK);
  259                 if (fcntl (FileHandle, F_GETLK, &fl) != -1 && fl.l_type != F_UNLCK)
  260                 {
  261                     errno = EAGAIN;
  262                     throw SystemException (SRC_POS, wstring (path));
  263                 }
  264                 break;
  265 
  266             case ShareReadWriteIgnoreLock:
  267                 break;
  268 
  269             default:
  270                 throw ParameterIncorrect (SRC_POS);
  271             }
  272         }
  273         catch (...)
  274         {
  275             close (FileHandle);
  276             throw;
  277         }
  278 #endif // 0
  279 
  280         Path = path;
  281         mFileOpenFlags = flags;
  282         FileIsOpen = true;
  283     }
  284 
  285     uint64 File::Read (const BufferPtr &buffer) const
  286     {
  287         if_debug (ValidateState());
  288 
  289 #ifdef TC_TRACE_FILE_OPERATIONS
  290         TraceFileOperation (FileHandle, Path, false, buffer.Size());
  291 #endif
  292         ssize_t bytesRead = read (FileHandle, buffer, buffer.Size());
  293         throw_sys_sub_if (bytesRead == -1, wstring (Path));
  294 
  295         return bytesRead;
  296     }
  297 
  298     uint64 File::ReadAt (const BufferPtr &buffer, uint64 position) const
  299     {
  300         if_debug (ValidateState());
  301 
  302 #ifdef TC_TRACE_FILE_OPERATIONS
  303         TraceFileOperation (FileHandle, Path, false, buffer.Size(), position);
  304 #endif
  305         ssize_t bytesRead = pread (FileHandle, buffer, buffer.Size(), position);
  306         throw_sys_sub_if (bytesRead == -1, wstring (Path));
  307 
  308         return bytesRead;
  309     }
  310 
  311     void File::SeekAt (uint64 position) const
  312     {
  313         if_debug (ValidateState());
  314         throw_sys_sub_if (lseek (FileHandle, position, SEEK_SET) == -1, wstring (Path));
  315     }
  316 
  317     void File::SeekEnd (int offset) const
  318     {
  319         if_debug (ValidateState());
  320 
  321         // BSD does not support seeking to the end of a device
  322 #ifdef TC_BSD
  323         if (Path.IsBlockDevice() || Path.IsCharacterDevice())
  324         {
  325             SeekAt (Length() + offset);
  326             return;
  327         }
  328 #endif
  329 
  330         throw_sys_sub_if (lseek (FileHandle, offset, SEEK_END) == -1, wstring (Path));
  331     }
  332 
  333     void File::Write (const ConstBufferPtr &buffer) const
  334     {
  335         if_debug (ValidateState());
  336 
  337 #ifdef TC_TRACE_FILE_OPERATIONS
  338         TraceFileOperation (FileHandle, Path, true, buffer.Size());
  339 #endif
  340         throw_sys_sub_if (write (FileHandle, buffer, buffer.Size()) != (ssize_t) buffer.Size(), wstring (Path));
  341     }
  342 
  343     void File::WriteAt (const ConstBufferPtr &buffer, uint64 position) const
  344     {
  345         if_debug (ValidateState());
  346 
  347 #ifdef TC_TRACE_FILE_OPERATIONS
  348         TraceFileOperation (FileHandle, Path, true, buffer.Size(), position);
  349 #endif
  350         throw_sys_sub_if (pwrite (FileHandle, buffer, buffer.Size(), position) != (ssize_t) buffer.Size(), wstring (Path));
  351     }
  352 }