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.

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

mercurial