other-licenses/7zstub/src/7zip/Common/FileStreams.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 // FileStreams.cpp
     3 #include "StdAfx.h"
     5 #ifndef _WIN32
     6 #include <fcntl.h>
     7 #include <unistd.h>
     8 #include <errno.h>
     9 #endif
    11 #include "FileStreams.h"
    13 static inline HRESULT ConvertBoolToHRESULT(bool result)
    14 {
    15   // return result ? S_OK: E_FAIL;
    16   #ifdef _WIN32
    17   return result ? S_OK: (::GetLastError());
    18   #else
    19   return result ? S_OK: E_FAIL;
    20   #endif
    21 }
    23 bool CInFileStream::Open(LPCTSTR fileName)
    24 {
    25   return File.Open(fileName);
    26 }
    28 #ifdef _WIN32
    29 #ifndef _UNICODE
    30 bool CInFileStream::Open(LPCWSTR fileName)
    31 {
    32   return File.Open(fileName);
    33 }
    34 #endif
    35 #endif
    37 STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
    38 {
    39   #ifdef _WIN32
    41   UInt32 realProcessedSize;
    42   bool result = File.ReadPart(data, size, realProcessedSize);
    43   if(processedSize != NULL)
    44     *processedSize = realProcessedSize;
    45   return ConvertBoolToHRESULT(result);
    47   #else
    49   if(processedSize != NULL)
    50     *processedSize = 0;
    51   ssize_t res = File.Read(data, (size_t)size);
    52   if (res == -1)
    53     return E_FAIL;
    54   if(processedSize != NULL)
    55     *processedSize = (UInt32)res;
    56   return S_OK;
    58   #endif
    59 }
    61 #ifndef _WIN32_WCE
    62 STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
    63 {
    64   #ifdef _WIN32
    65   UInt32 realProcessedSize;
    66   BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), 
    67       data, size, (DWORD *)&realProcessedSize, NULL);
    68   if(processedSize != NULL)
    69     *processedSize = realProcessedSize;
    70   if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
    71     return S_OK;
    72   return ConvertBoolToHRESULT(res != FALSE);
    74   #else
    76   if(processedSize != NULL)
    77     *processedSize = 0;
    78   ssize_t res;
    79   do 
    80   {
    81     res = read(0, data, (size_t)size);
    82   } 
    83   while (res < 0 && (errno == EINTR));
    84   if (res == -1)
    85     return E_FAIL;
    86   if(processedSize != NULL)
    87     *processedSize = (UInt32)res;
    88   return S_OK;
    90   #endif
    91 }
    93 #endif
    95 STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, 
    96     UInt64 *newPosition)
    97 {
    98   if(seekOrigin >= 3)
    99     return STG_E_INVALIDFUNCTION;
   101   #ifdef _WIN32
   103   UInt64 realNewPosition;
   104   bool result = File.Seek(offset, seekOrigin, realNewPosition);
   105   if(newPosition != NULL)
   106     *newPosition = realNewPosition;
   107   return ConvertBoolToHRESULT(result);
   109   #else
   111   off_t res = File.Seek(offset, seekOrigin);
   112   if (res == -1)
   113     return E_FAIL;
   114   if(newPosition != NULL)
   115     *newPosition = (UInt64)res;
   116   return S_OK;
   118   #endif
   119 }
   121 STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
   122 {
   123   return ConvertBoolToHRESULT(File.GetLength(*size));
   124 }
   127 //////////////////////////
   128 // COutFileStream
   130 bool COutFileStream::Create(LPCTSTR fileName, bool createAlways)
   131 {
   132   return File.Create(fileName, createAlways);
   133 }
   135 #ifdef _WIN32
   136 #ifndef _UNICODE
   137 bool COutFileStream::Create(LPCWSTR fileName, bool createAlways)
   138 {
   139   return File.Create(fileName, createAlways);
   140 }
   141 #endif
   142 #endif
   144 STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
   145 {
   146   #ifdef _WIN32
   148   UInt32 realProcessedSize;
   149   bool result = File.WritePart(data, size, realProcessedSize);
   150   if(processedSize != NULL)
   151     *processedSize = realProcessedSize;
   152   return ConvertBoolToHRESULT(result);
   154   #else
   156   if(processedSize != NULL)
   157     *processedSize = 0;
   158   ssize_t res = File.Write(data, (size_t)size);
   159   if (res == -1)
   160     return E_FAIL;
   161   if(processedSize != NULL)
   162     *processedSize = (UInt32)res;
   163   return S_OK;
   165   #endif
   166 }
   168 STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, 
   169     UInt64 *newPosition)
   170 {
   171   if(seekOrigin >= 3)
   172     return STG_E_INVALIDFUNCTION;
   173   #ifdef _WIN32
   175   UInt64 realNewPosition;
   176   bool result = File.Seek(offset, seekOrigin, realNewPosition);
   177   if(newPosition != NULL)
   178     *newPosition = realNewPosition;
   179   return ConvertBoolToHRESULT(result);
   181   #else
   183   off_t res = File.Seek(offset, seekOrigin);
   184   if (res == -1)
   185     return E_FAIL;
   186   if(newPosition != NULL)
   187     *newPosition = (UInt64)res;
   188   return S_OK;
   190   #endif
   191 }
   193 STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
   194 {
   195   #ifdef _WIN32
   196   UInt64 currentPos;
   197   if(!File.Seek(0, FILE_CURRENT, currentPos))
   198     return E_FAIL;
   199   bool result = File.SetLength(newSize);
   200   UInt64 currentPos2;
   201   result = result && File.Seek(currentPos, currentPos2);
   202   return result ? S_OK : E_FAIL;
   203   #else
   204   return E_FAIL;
   205   #endif
   206 }
   208 #ifndef _WIN32_WCE
   209 STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
   210 {
   211   if(processedSize != NULL)
   212     *processedSize = 0;
   214   #ifdef _WIN32
   215   UInt32 realProcessedSize;
   216   BOOL res = TRUE;
   217   if (size > 0)
   218   {
   219     // Seems that Windows doesn't like big amounts writing to stdout.
   220     // So we limit portions by 32KB.
   221     UInt32 sizeTemp = (1 << 15); 
   222     if (sizeTemp > size)
   223       sizeTemp = size;
   224     res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), 
   225         data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
   226     size -= realProcessedSize;
   227     data = (const void *)((const Byte *)data + realProcessedSize);
   228     if(processedSize != NULL)
   229       *processedSize += realProcessedSize;
   230   }
   231   return ConvertBoolToHRESULT(res != FALSE);
   233   #else
   235   ssize_t res;
   236   do 
   237   {
   238     res = write(1, data, (size_t)size);
   239   } 
   240   while (res < 0 && (errno == EINTR));
   241   if (res == -1)
   242     return E_FAIL;
   243   if(processedSize != NULL)
   244     *processedSize = (UInt32)res;
   245   return S_OK;
   247   return S_OK;
   248   #endif
   249 }
   251 #endif

mercurial