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

changeset 0
6474c204b198
     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 +}}}

mercurial