other-licenses/7zstub/src/Windows/FileIO.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Windows/FileIO.cpp
michael@0 2
michael@0 3 #include "StdAfx.h"
michael@0 4
michael@0 5 #include "FileIO.h"
michael@0 6 #include "Defs.h"
michael@0 7 #ifndef _UNICODE
michael@0 8 #include "../Common/StringConvert.h"
michael@0 9 #endif
michael@0 10
michael@0 11 #ifndef _UNICODE
michael@0 12 extern bool g_IsNT;
michael@0 13 #endif
michael@0 14
michael@0 15 namespace NWindows {
michael@0 16 namespace NFile {
michael@0 17 namespace NIO {
michael@0 18
michael@0 19 CFileBase::~CFileBase() { Close(); }
michael@0 20
michael@0 21 bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
michael@0 22 DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
michael@0 23 {
michael@0 24 Close();
michael@0 25 _handle = ::CreateFile(fileName, desiredAccess, shareMode,
michael@0 26 (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
michael@0 27 flagsAndAttributes, (HANDLE) NULL);
michael@0 28 return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE));
michael@0 29 }
michael@0 30
michael@0 31 #ifndef _UNICODE
michael@0 32 bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
michael@0 33 DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
michael@0 34 {
michael@0 35 if (g_IsNT)
michael@0 36 {
michael@0 37 Close();
michael@0 38 _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
michael@0 39 (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
michael@0 40 flagsAndAttributes, (HANDLE) NULL);
michael@0 41 return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE));
michael@0 42 }
michael@0 43 return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
michael@0 44 desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
michael@0 45 }
michael@0 46 #endif
michael@0 47
michael@0 48 bool CFileBase::Close()
michael@0 49 {
michael@0 50 if(!_fileIsOpen)
michael@0 51 return true;
michael@0 52 bool result = BOOLToBool(::CloseHandle(_handle));
michael@0 53 _fileIsOpen = !result;
michael@0 54 return result;
michael@0 55 }
michael@0 56
michael@0 57 bool CFileBase::GetPosition(UInt64 &position) const
michael@0 58 {
michael@0 59 return Seek(0, FILE_CURRENT, position);
michael@0 60 }
michael@0 61
michael@0 62 bool CFileBase::GetLength(UInt64 &length) const
michael@0 63 {
michael@0 64 DWORD sizeHigh;
michael@0 65 DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
michael@0 66 if(sizeLow == 0xFFFFFFFF)
michael@0 67 if(::GetLastError() != NO_ERROR)
michael@0 68 return false;
michael@0 69 length = (((UInt64)sizeHigh) << 32) + sizeLow;
michael@0 70 return true;
michael@0 71 }
michael@0 72
michael@0 73 bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
michael@0 74 {
michael@0 75 LARGE_INTEGER value;
michael@0 76 value.QuadPart = distanceToMove;
michael@0 77 value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
michael@0 78 if (value.LowPart == 0xFFFFFFFF)
michael@0 79 if(::GetLastError() != NO_ERROR)
michael@0 80 return false;
michael@0 81 newPosition = value.QuadPart;
michael@0 82 return true;
michael@0 83 }
michael@0 84
michael@0 85 bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
michael@0 86 {
michael@0 87 return Seek(position, FILE_BEGIN, newPosition);
michael@0 88 }
michael@0 89
michael@0 90 bool CFileBase::SeekToBegin()
michael@0 91 {
michael@0 92 UInt64 newPosition;
michael@0 93 return Seek(0, newPosition);
michael@0 94 }
michael@0 95
michael@0 96 bool CFileBase::SeekToEnd(UInt64 &newPosition)
michael@0 97 {
michael@0 98 return Seek(0, FILE_END, newPosition);
michael@0 99 }
michael@0 100
michael@0 101 bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
michael@0 102 {
michael@0 103 BY_HANDLE_FILE_INFORMATION winFileInfo;
michael@0 104 if(!::GetFileInformationByHandle(_handle, &winFileInfo))
michael@0 105 return false;
michael@0 106 fileInfo.Attributes = winFileInfo.dwFileAttributes;
michael@0 107 fileInfo.CreationTime = winFileInfo.ftCreationTime;
michael@0 108 fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
michael@0 109 fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
michael@0 110 fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
michael@0 111 fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
michael@0 112 fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
michael@0 113 fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
michael@0 114 return true;
michael@0 115 }
michael@0 116
michael@0 117 /////////////////////////
michael@0 118 // CInFile
michael@0 119
michael@0 120 bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
michael@0 121 { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
michael@0 122
michael@0 123 bool CInFile::Open(LPCTSTR fileName)
michael@0 124 { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
michael@0 125
michael@0 126 #ifndef _UNICODE
michael@0 127 bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
michael@0 128 { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
michael@0 129
michael@0 130 bool CInFile::Open(LPCWSTR fileName)
michael@0 131 { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
michael@0 132 #endif
michael@0 133
michael@0 134 // ReadFile and WriteFile functions in Windows have BUG:
michael@0 135 // If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
michael@0 136 // from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
michael@0 137 // (Insufficient system resources exist to complete the requested service).
michael@0 138
michael@0 139 static UInt32 kChunkSizeMax = (1 << 24);
michael@0 140
michael@0 141 bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
michael@0 142 {
michael@0 143 if (size > kChunkSizeMax)
michael@0 144 size = kChunkSizeMax;
michael@0 145 DWORD processedLoc = 0;
michael@0 146 bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
michael@0 147 processedSize = (UInt32)processedLoc;
michael@0 148 return res;
michael@0 149 }
michael@0 150
michael@0 151 bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
michael@0 152 {
michael@0 153 processedSize = 0;
michael@0 154 do
michael@0 155 {
michael@0 156 UInt32 processedLoc = 0;
michael@0 157 bool res = ReadPart(data, size, processedLoc);
michael@0 158 processedSize += processedLoc;
michael@0 159 if (!res)
michael@0 160 return false;
michael@0 161 if (processedLoc == 0)
michael@0 162 return true;
michael@0 163 data = (void *)((unsigned char *)data + processedLoc);
michael@0 164 size -= processedLoc;
michael@0 165 }
michael@0 166 while (size > 0);
michael@0 167 return true;
michael@0 168 }
michael@0 169
michael@0 170 /////////////////////////
michael@0 171 // COutFile
michael@0 172
michael@0 173 bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
michael@0 174 { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
michael@0 175
michael@0 176 static inline DWORD GetCreationDisposition(bool createAlways)
michael@0 177 { return createAlways? CREATE_ALWAYS: CREATE_NEW; }
michael@0 178
michael@0 179 bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
michael@0 180 { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
michael@0 181
michael@0 182 bool COutFile::Create(LPCTSTR fileName, bool createAlways)
michael@0 183 { return Open(fileName, GetCreationDisposition(createAlways)); }
michael@0 184
michael@0 185 #ifndef _UNICODE
michael@0 186
michael@0 187 bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
michael@0 188 { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
michael@0 189
michael@0 190 bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
michael@0 191 { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
michael@0 192
michael@0 193 bool COutFile::Create(LPCWSTR fileName, bool createAlways)
michael@0 194 { return Open(fileName, GetCreationDisposition(createAlways)); }
michael@0 195
michael@0 196 #endif
michael@0 197
michael@0 198 bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
michael@0 199 { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
michael@0 200
michael@0 201 bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
michael@0 202 { return SetTime(NULL, NULL, lastWriteTime); }
michael@0 203
michael@0 204 bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
michael@0 205 {
michael@0 206 if (size > kChunkSizeMax)
michael@0 207 size = kChunkSizeMax;
michael@0 208 DWORD processedLoc = 0;
michael@0 209 bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
michael@0 210 processedSize = (UInt32)processedLoc;
michael@0 211 return res;
michael@0 212 }
michael@0 213
michael@0 214 bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
michael@0 215 {
michael@0 216 processedSize = 0;
michael@0 217 do
michael@0 218 {
michael@0 219 UInt32 processedLoc = 0;
michael@0 220 bool res = WritePart(data, size, processedLoc);
michael@0 221 processedSize += processedLoc;
michael@0 222 if (!res)
michael@0 223 return false;
michael@0 224 if (processedLoc == 0)
michael@0 225 return true;
michael@0 226 data = (const void *)((const unsigned char *)data + processedLoc);
michael@0 227 size -= processedLoc;
michael@0 228 }
michael@0 229 while (size > 0);
michael@0 230 return true;
michael@0 231 }
michael@0 232
michael@0 233 bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
michael@0 234
michael@0 235 bool COutFile::SetLength(UInt64 length)
michael@0 236 {
michael@0 237 UInt64 newPosition;
michael@0 238 if(!Seek(length, newPosition))
michael@0 239 return false;
michael@0 240 if(newPosition != length)
michael@0 241 return false;
michael@0 242 return SetEndOfFile();
michael@0 243 }
michael@0 244
michael@0 245 }}}

mercurial