00001
00002
00003
00004
00005 #include "StdAfx.h"
00006
00007 #include "FileIO.h"
00008 #include "Defs.h"
00009 #ifndef _UNICODE
00010 #include "StringConvert.h"
00011 #endif
00012
00013 #ifndef _UNICODE
00014 extern bool g_IsNT;
00015 #endif
00016
00017 namespace NWindows {
00018 namespace NFile {
00019 namespace NIO {
00020
00021 CFileBase::~CFileBase() { Close(); }
00022
00023 bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
00024 DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
00025 {
00026 Close();
00027 _handle = ::CreateFile(fileName, desiredAccess, shareMode,
00028 (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
00029 flagsAndAttributes, (HANDLE) NULL);
00030 return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE));
00031 }
00032
00033 #ifndef _UNICODE
00034 bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
00035 DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
00036 {
00037 if (g_IsNT)
00038 {
00039 Close();
00040 _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
00041 (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
00042 flagsAndAttributes, (HANDLE) NULL);
00043 return (_fileIsOpen = (_handle != INVALID_HANDLE_VALUE));
00044 }
00045 return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
00046 desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
00047 }
00048 #endif
00049
00050 bool CFileBase::Close()
00051 {
00052 if(!_fileIsOpen)
00053 return true;
00054 bool result = BOOLToBool(::CloseHandle(_handle));
00055 _fileIsOpen = !result;
00056 return result;
00057 }
00058
00059 bool CFileBase::GetPosition(UInt64 &position) const
00060 {
00061 return Seek(0, FILE_CURRENT, position);
00062 }
00063
00064 bool CFileBase::GetLength(UInt64 &length) const
00065 {
00066 DWORD sizeHigh;
00067 DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
00068 if(sizeLow == 0xFFFFFFFF)
00069 if(::GetLastError() != NO_ERROR)
00070 return false;
00071 length = (((UInt64)sizeHigh) << 32) + sizeLow;
00072 return true;
00073 }
00074
00075 bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
00076 {
00077 LARGE_INTEGER value;
00078 value.QuadPart = distanceToMove;
00079 value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
00080 if (value.LowPart == 0xFFFFFFFF)
00081 if(::GetLastError() != NO_ERROR)
00082 return false;
00083 newPosition = value.QuadPart;
00084 return true;
00085 }
00086
00087 bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
00088 {
00089 return Seek(position, FILE_BEGIN, newPosition);
00090 }
00091
00092 bool CFileBase::SeekToBegin()
00093 {
00094 UInt64 newPosition;
00095 return Seek(0, newPosition);
00096 }
00097
00098 bool CFileBase::SeekToEnd(UInt64 &newPosition)
00099 {
00100 return Seek(0, FILE_END, newPosition);
00101 }
00102
00103 bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
00104 {
00105 BY_HANDLE_FILE_INFORMATION winFileInfo;
00106 if(!::GetFileInformationByHandle(_handle, &winFileInfo))
00107 return false;
00108 fileInfo.Attributes = winFileInfo.dwFileAttributes;
00109 fileInfo.CreationTime = winFileInfo.ftCreationTime;
00110 fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
00111 fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
00112 fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
00113 fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
00114 fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
00115 fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
00116 return true;
00117 }
00118
00119 bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
00120 { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
00121
00122 bool CInFile::Open(LPCTSTR fileName)
00123 { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
00124
00125 #ifndef _UNICODE
00126 bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
00127 { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
00128
00129 bool CInFile::Open(LPCWSTR fileName)
00130 { return Open(fileName, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
00131 #endif
00132
00133 static UInt32 kChunkSizeMax = (1 << 24);
00134
00135 bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
00136 {
00137 if (size > kChunkSizeMax)
00138 size = kChunkSizeMax;
00139 DWORD processedLoc = 0;
00140 bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
00141 processedSize = (UInt32)processedLoc;
00142 return res;
00143 }
00144
00145 bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
00146 {
00147 processedSize = 0;
00148 do
00149 {
00150 UInt32 processedLoc = 0;
00151 bool res = ReadPart(data, size, processedLoc);
00152 processedSize += processedLoc;
00153 if (!res)
00154 return false;
00155 if (processedLoc == 0)
00156 return true;
00157 data = (void *)((unsigned char *)data + processedLoc);
00158 size -= processedLoc;
00159 }
00160 while (size > 0);
00161 return true;
00162 }
00163
00164 bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
00165 { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
00166
00167 static inline DWORD GetCreationDisposition(bool createAlways)
00168 { return createAlways? CREATE_ALWAYS: CREATE_NEW; }
00169
00170 bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
00171 { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
00172
00173 bool COutFile::Create(LPCTSTR fileName, bool createAlways)
00174 { return Open(fileName, GetCreationDisposition(createAlways)); }
00175
00176 #ifndef _UNICODE
00177
00178 bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
00179 { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
00180
00181 bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
00182 { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
00183
00184 bool COutFile::Create(LPCWSTR fileName, bool createAlways)
00185 { return Open(fileName, GetCreationDisposition(createAlways)); }
00186
00187 #endif
00188
00189 bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
00190 { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
00191
00192 bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
00193 { return SetTime(NULL, NULL, lastWriteTime); }
00194
00195 bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
00196 {
00197 if (size > kChunkSizeMax)
00198 size = kChunkSizeMax;
00199 DWORD processedLoc = 0;
00200 bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
00201 processedSize = (UInt32)processedLoc;
00202 return res;
00203 }
00204
00205 bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
00206 {
00207 processedSize = 0;
00208 do
00209 {
00210 UInt32 processedLoc = 0;
00211 bool res = WritePart(data, size, processedLoc);
00212 processedSize += processedLoc;
00213 if (!res)
00214 return false;
00215 if (processedLoc == 0)
00216 return true;
00217 data = (const void *)((const unsigned char *)data + processedLoc);
00218 size -= processedLoc;
00219 }
00220 while (size > 0);
00221 return true;
00222 }
00223
00224 bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
00225
00226 bool COutFile::SetLength(UInt64 length)
00227 {
00228 UInt64 newPosition;
00229 if(!Seek(length, newPosition))
00230 return false;
00231 if(newPosition != length)
00232 return false;
00233 return SetEndOfFile();
00234 }
00235
00236 }}}