1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/other-licenses/7zstub/src/Windows/FileIO.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,245 @@ 1.4 +// Windows/FileIO.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "FileIO.h" 1.9 +#include "Defs.h" 1.10 +#ifndef _UNICODE 1.11 +#include "../Common/StringConvert.h" 1.12 +#endif 1.13 + 1.14 +#ifndef _UNICODE 1.15 +extern bool g_IsNT; 1.16 +#endif 1.17 + 1.18 +namespace NWindows { 1.19 +namespace NFile { 1.20 +namespace NIO { 1.21 + 1.22 +CFileBase::~CFileBase() { Close(); } 1.23 + 1.24 +bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess, 1.25 + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 1.26 +{ 1.27 + Close(); 1.28 + _handle = ::CreateFile(fileName, desiredAccess, shareMode, 1.29 + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, 1.30 + flagsAndAttributes, (HANDLE) NULL); 1.31 + return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE)); 1.32 +} 1.33 + 1.34 +#ifndef _UNICODE 1.35 +bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, 1.36 + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 1.37 +{ 1.38 + if (g_IsNT) 1.39 + { 1.40 + Close(); 1.41 + _handle = ::CreateFileW(fileName, desiredAccess, shareMode, 1.42 + (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, 1.43 + flagsAndAttributes, (HANDLE) NULL); 1.44 + return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE)); 1.45 + } 1.46 + return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP), 1.47 + desiredAccess, shareMode, creationDisposition, flagsAndAttributes); 1.48 +} 1.49 +#endif 1.50 + 1.51 +bool CFileBase::Close() 1.52 +{ 1.53 + if(!_fileIsOpen) 1.54 + return true; 1.55 + bool result = BOOLToBool(::CloseHandle(_handle)); 1.56 + _fileIsOpen = !result; 1.57 + return result; 1.58 +} 1.59 + 1.60 +bool CFileBase::GetPosition(UInt64 &position) const 1.61 +{ 1.62 + return Seek(0, FILE_CURRENT, position); 1.63 +} 1.64 + 1.65 +bool CFileBase::GetLength(UInt64 &length) const 1.66 +{ 1.67 + DWORD sizeHigh; 1.68 + DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh); 1.69 + if(sizeLow == 0xFFFFFFFF) 1.70 + if(::GetLastError() != NO_ERROR) 1.71 + return false; 1.72 + length = (((UInt64)sizeHigh) << 32) + sizeLow; 1.73 + return true; 1.74 +} 1.75 + 1.76 +bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const 1.77 +{ 1.78 + LARGE_INTEGER value; 1.79 + value.QuadPart = distanceToMove; 1.80 + value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod); 1.81 + if (value.LowPart == 0xFFFFFFFF) 1.82 + if(::GetLastError() != NO_ERROR) 1.83 + return false; 1.84 + newPosition = value.QuadPart; 1.85 + return true; 1.86 +} 1.87 + 1.88 +bool CFileBase::Seek(UInt64 position, UInt64 &newPosition) 1.89 +{ 1.90 + return Seek(position, FILE_BEGIN, newPosition); 1.91 +} 1.92 + 1.93 +bool CFileBase::SeekToBegin() 1.94 +{ 1.95 + UInt64 newPosition; 1.96 + return Seek(0, newPosition); 1.97 +} 1.98 + 1.99 +bool CFileBase::SeekToEnd(UInt64 &newPosition) 1.100 +{ 1.101 + return Seek(0, FILE_END, newPosition); 1.102 +} 1.103 + 1.104 +bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const 1.105 +{ 1.106 + BY_HANDLE_FILE_INFORMATION winFileInfo; 1.107 + if(!::GetFileInformationByHandle(_handle, &winFileInfo)) 1.108 + return false; 1.109 + fileInfo.Attributes = winFileInfo.dwFileAttributes; 1.110 + fileInfo.CreationTime = winFileInfo.ftCreationTime; 1.111 + fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime; 1.112 + fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime; 1.113 + fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes; 1.114 + fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow; 1.115 + fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks; 1.116 + fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow; 1.117 + return true; 1.118 +} 1.119 + 1.120 +///////////////////////// 1.121 +// CInFile 1.122 + 1.123 +bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 1.124 + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } 1.125 + 1.126 +bool CInFile::Open(LPCTSTR fileName) 1.127 + { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } 1.128 + 1.129 +#ifndef _UNICODE 1.130 +bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 1.131 + { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); } 1.132 + 1.133 +bool CInFile::Open(LPCWSTR fileName) 1.134 + { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); } 1.135 +#endif 1.136 + 1.137 +// ReadFile and WriteFile functions in Windows have BUG: 1.138 +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) 1.139 +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES 1.140 +// (Insufficient system resources exist to complete the requested service). 1.141 + 1.142 +static UInt32 kChunkSizeMax = (1 << 24); 1.143 + 1.144 +bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize) 1.145 +{ 1.146 + if (size > kChunkSizeMax) 1.147 + size = kChunkSizeMax; 1.148 + DWORD processedLoc = 0; 1.149 + bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); 1.150 + processedSize = (UInt32)processedLoc; 1.151 + return res; 1.152 +} 1.153 + 1.154 +bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize) 1.155 +{ 1.156 + processedSize = 0; 1.157 + do 1.158 + { 1.159 + UInt32 processedLoc = 0; 1.160 + bool res = ReadPart(data, size, processedLoc); 1.161 + processedSize += processedLoc; 1.162 + if (!res) 1.163 + return false; 1.164 + if (processedLoc == 0) 1.165 + return true; 1.166 + data = (void *)((unsigned char *)data + processedLoc); 1.167 + size -= processedLoc; 1.168 + } 1.169 + while (size > 0); 1.170 + return true; 1.171 +} 1.172 + 1.173 +///////////////////////// 1.174 +// COutFile 1.175 + 1.176 +bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 1.177 + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } 1.178 + 1.179 +static inline DWORD GetCreationDisposition(bool createAlways) 1.180 + { return createAlways? CREATE_ALWAYS: CREATE_NEW; } 1.181 + 1.182 +bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition) 1.183 + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } 1.184 + 1.185 +bool COutFile::Create(LPCTSTR fileName, bool createAlways) 1.186 + { return Open(fileName, GetCreationDisposition(createAlways)); } 1.187 + 1.188 +#ifndef _UNICODE 1.189 + 1.190 +bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes) 1.191 + { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); } 1.192 + 1.193 +bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition) 1.194 + { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); } 1.195 + 1.196 +bool COutFile::Create(LPCWSTR fileName, bool createAlways) 1.197 + { return Open(fileName, GetCreationDisposition(createAlways)); } 1.198 + 1.199 +#endif 1.200 + 1.201 +bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime) 1.202 + { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); } 1.203 + 1.204 +bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime) 1.205 + { return SetTime(NULL, NULL, lastWriteTime); } 1.206 + 1.207 +bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize) 1.208 +{ 1.209 + if (size > kChunkSizeMax) 1.210 + size = kChunkSizeMax; 1.211 + DWORD processedLoc = 0; 1.212 + bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL)); 1.213 + processedSize = (UInt32)processedLoc; 1.214 + return res; 1.215 +} 1.216 + 1.217 +bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) 1.218 +{ 1.219 + processedSize = 0; 1.220 + do 1.221 + { 1.222 + UInt32 processedLoc = 0; 1.223 + bool res = WritePart(data, size, processedLoc); 1.224 + processedSize += processedLoc; 1.225 + if (!res) 1.226 + return false; 1.227 + if (processedLoc == 0) 1.228 + return true; 1.229 + data = (const void *)((const unsigned char *)data + processedLoc); 1.230 + size -= processedLoc; 1.231 + } 1.232 + while (size > 0); 1.233 + return true; 1.234 +} 1.235 + 1.236 +bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); } 1.237 + 1.238 +bool COutFile::SetLength(UInt64 length) 1.239 +{ 1.240 + UInt64 newPosition; 1.241 + if(!Seek(length, newPosition)) 1.242 + return false; 1.243 + if(newPosition != length) 1.244 + return false; 1.245 + return SetEndOfFile(); 1.246 +} 1.247 + 1.248 +}}}