static bool ReadDataString(CFSTR fileName, LPCSTR startID, LPCSTR endID, AString &stringResult) { stringResult.Empty(); NIO::CInFile inFile; if (!inFile.Open(fileName)) return false; const int kBufferSize = (1 << 12); Byte buffer[kBufferSize]; int signatureStartSize = MyStringLen(startID); int signatureEndSize = MyStringLen(endID); UInt32 numBytesPrev = 0; bool writeMode = false; UInt64 posTotal = 0; for (;;) { if (posTotal > (1 << 20)) return (stringResult.IsEmpty()); UInt32 numReadBytes = kBufferSize - numBytesPrev; UInt32 processedSize; if (!inFile.Read(buffer + numBytesPrev, numReadBytes, processedSize)) return false; if (processedSize == 0) return true; UInt32 numBytesInBuffer = numBytesPrev + processedSize; UInt32 pos = 0; for (;;) { if (writeMode) { if (pos > numBytesInBuffer - signatureEndSize) break; if (memcmp(buffer + pos, endID, signatureEndSize) == 0) return true; char b = buffer[pos]; if (b == 0) return false; stringResult += b; pos++; } else { if (pos > numBytesInBuffer - signatureStartSize) break; if (memcmp(buffer + pos, startID, signatureStartSize) == 0) { writeMode = true; pos += signatureStartSize; } else pos++; } } numBytesPrev = numBytesInBuffer - pos; posTotal += pos; memmove(buffer, buffer + pos, numBytesPrev); } }
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) { if (!_outFile.Close()) return E_FAIL; UInt64 size = 0; UInt32 crc = CRC_INIT_VAL; if (_bufPos > 0) { RINOK(WriteStream(stream, _buf, _bufPos)); crc = CrcUpdate(crc, _buf, _bufPos); size += _bufPos; } if (_tempFileCreated) { NIO::CInFile inFile; if (!inFile.Open(_tempFileName)) return E_FAIL; while (size < _size) { UInt32 processed; if (!inFile.ReadPart(_buf, kTempBufSize, processed)) return E_FAIL; if (processed == 0) break; RINOK(WriteStream(stream, _buf, processed)); crc = CrcUpdate(crc, _buf, processed); size += processed; } } return (_crc == crc && size == _size) ? S_OK : E_FAIL; }
static bool GetSymLink(CFSTR path, CReparseAttr &attr) { NIO::CInFile file; if (!file.Open(path, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS)) return false; const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; CByteArr buf(kBufSize); DWORD returnedSize; if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize)) return false; if (!attr.Parse(buf, returnedSize)) return false; CByteBuffer data2; if (!FillLinkData(data2, attr.GetPath(), attr.IsSymLink())) return false; if (data2.Size() != returnedSize || memcmp(data2, buf, returnedSize) != 0) return false; return true; }
bool CFSFolder::LoadComments() { _comments.Clear(); _commentsAreLoaded = true; NIO::CInFile file; if (!file.Open(_path + kDescriptionFileName)) return false; UInt64 len; if (!file.GetLength(len)) return false; if (len >= (1 << 28)) return false; AString s; char *p = s.GetBuf((unsigned)(size_t)len); UInt32 processedSize; file.Read(p, (UInt32)len, processedSize); s.ReleaseBuf_CalcLen((unsigned)(size_t)len); if (processedSize != len) return false; file.Close(); UString unicodeString; if (!ConvertUTF8ToUnicode(s, unicodeString)) return false; return _comments.ReadFromString(unicodeString); }
bool CFSFolder::LoadComments() { if (_commentsAreLoaded) return true; _comments.Clear(); _commentsAreLoaded = true; NIO::CInFile file; if (!file.Open(_path + kDescriptionFileName)) return false; UInt64 length; if (!file.GetLength(length)) return false; if (length >= (1 << 28)) return false; AString s; char *p = s.GetBuffer((int)((size_t)length + 1)); UInt32 processedSize; file.Read(p, (UInt32)length, processedSize); p[length] = 0; s.ReleaseBuffer(); if (processedSize != length) return false; file.Close(); UString unicodeString; if (!ConvertUTF8ToUnicode(s, unicodeString)) return false; return _comments.ReadFromString(unicodeString); }
static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt64 fileSize, UInt32 bufferSize, UInt64 progressStart, IProgress *progress) { NIO::CInFile inFile; if (!inFile.Open(fromPath)) return GetLastError(); if (fileSize == (UInt64)(Int64)-1) { if (!inFile.GetLength(fileSize)) ::GetLastError(); } NIO::COutFile outFile; if (writeToDisk) { if (!outFile.Open(toPath, FILE_SHARE_WRITE, OPEN_EXISTING, 0)) return GetLastError(); } else if (!outFile.Create(toPath, true)) return GetLastError(); CPhysTempBuffer tempBuffer; tempBuffer.buffer = MidAlloc(bufferSize); if (!tempBuffer.buffer) return E_OUTOFMEMORY; for (UInt64 pos = 0; pos < fileSize;) { UInt64 progressCur = progressStart + pos; RINOK(progress->SetCompleted(&progressCur)); UInt64 rem = fileSize - pos; UInt32 curSize = (UInt32)MyMin(rem, (UInt64)bufferSize); UInt32 processedSize; if (!inFile.Read(tempBuffer.buffer, curSize, processedSize)) return GetLastError(); if (processedSize == 0) break; curSize = processedSize; if (writeToDisk) { const UInt32 kMask = 0x1FF; curSize = (curSize + kMask) & ~kMask; if (curSize > bufferSize) return E_FAIL; } if (!outFile.Write(tempBuffer.buffer, curSize, processedSize)) return GetLastError(); if (curSize != processedSize) return E_FAIL; pos += curSize; } return S_OK; }
HRESULT CThreadCombine::ProcessVirt() { NIO::COutFile outFile; if (!outFile.Create(OutputPath, false)) { HRESULT res = GetLastError(); AddErrorPath(OutputPath); return res; } CProgressSync &sync = Sync; sync.Set_NumBytesTotal(TotalSize); CMyBuffer bufferObject; if (!bufferObject.Allocate(kBufSize)) return E_OUTOFMEMORY; Byte *buffer = (Byte *)(void *)bufferObject; UInt64 pos = 0; FOR_VECTOR (i, Names) { NIO::CInFile inFile; const FString nextName = InputDirPrefix + Names[i]; if (!inFile.Open(nextName)) { HRESULT res = GetLastError(); AddErrorPath(nextName); return res; } sync.Set_FilePath(fs2us(nextName)); for (;;) { UInt32 processedSize; if (!inFile.Read(buffer, kBufSize, processedSize)) { HRESULT res = GetLastError(); AddErrorPath(nextName); return res; } if (processedSize == 0) break; UInt32 needSize = processedSize; if (!outFile.Write(buffer, needSize, processedSize)) { HRESULT res = GetLastError(); AddErrorPath(OutputPath); return res; } if (needSize != processedSize) throw g_Message_FileWriteError; pos += processedSize; RINOK(sync.Set_NumBytesCur(pos)); } }
// #ifndef _UNICODE bool CFileInfoW::Find(LPCWSTR wildcard) { #ifdef SUPPORT_DEVICE_FILE if (IsDeviceName(wildcard)) { Clear(); IsDevice = true; NIO::CInFile inFile; if (!inFile.Open(wildcard)) return false; Name = wildcard + 4; if (inFile.LengthDefined) Size = inFile.Length; return true; } #endif CFindFile finder; return finder.FindFirst(wildcard, *this); }
HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath, DWORD attrib) { ErrorFileIndex = -1; ErrorMessage.Empty(); CurrentSize = 0; { const size_t kBufSize = 1 << 16; CByteArr buf(kBufSize); NIO::CInFile inFile; NIO::COutFile outFile; if (!inFile.Open(inPath)) { ErrorFileIndex = 0; return S_OK; } if (!outFile.Create(outPath, true)) { ErrorFileIndex = 1; return S_OK; } for (;;) { UInt32 num; if (!inFile.Read(buf, kBufSize, num)) { ErrorFileIndex = 0; return S_OK; } if (num == 0) break; UInt32 written = 0; if (!outFile.Write(buf, num, written)) { ErrorFileIndex = 1; return S_OK; } if (written != num) { ErrorMessage = "Write error"; return S_OK; } CurrentSize += num; if (Progress) { UInt64 completed = StartPos + CurrentSize; RINOK(Progress->SetCompleted(&completed)); } } } if (attrib != INVALID_FILE_ATTRIBUTES) SetFileAttrib(outPath, attrib); if (DeleteSrcFile) { if (!DeleteFileAlways(inPath)) { ErrorFileIndex = 0; return S_OK; } } return S_OK; }
bool CFileInfo::Find(CFSTR path) { #ifdef SUPPORT_DEVICE_FILE if (IsDevicePath(path)) { ClearBase(); Name = path + 4; IsDevice = true; if (NName::IsDrivePath2(path + 4) && path[6] == 0) { FChar drive[4] = { path[4], ':', '\\', 0 }; UInt64 clusterSize, totalSize, freeSize; if (NSystem::MyGetDiskFreeSpace(drive, clusterSize, totalSize, freeSize)) { Size = totalSize; return true; } } NIO::CInFile inFile; // ::OutputDebugStringW(path); if (!inFile.Open(path)) return false; // ::OutputDebugStringW(L"---"); if (inFile.SizeDefined) Size = inFile.Size; return true; } #endif #if defined(_WIN32) && !defined(UNDER_CE) int colonPos = FindAltStreamColon(path); if (colonPos >= 0 && path[(unsigned)colonPos + 1] != 0) { UString streamName = fs2us(path + (unsigned)colonPos); FString filePath = path; filePath.DeleteFrom(colonPos); /* we allow both cases: name:stream name:stream:$DATA */ const unsigned kPostfixSize = 6; if (streamName.Len() <= kPostfixSize || !StringsAreEqualNoCase_Ascii(streamName.RightPtr(kPostfixSize), ":$DATA")) streamName += L":$DATA"; bool isOk = true; if (IsDrivePath2(filePath) && (colonPos == 2 || colonPos == 3 && filePath[2] == '\\')) { // FindFirstFile doesn't work for "c:\" and for "c:" (if current dir is ROOT) ClearBase(); Name.Empty(); if (colonPos == 2) Name = filePath; } else isOk = Find(filePath); if (isOk) { Attrib &= ~(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT); Size = 0; CStreamEnumerator enumerator(filePath); for (;;) { CStreamInfo si; bool found; if (!enumerator.Next(si, found)) return false; if (!found) { ::SetLastError(ERROR_FILE_NOT_FOUND); return false; } if (si.Name.IsEqualTo_NoCase(streamName)) { // we delete postfix, if alt stream name is not "::$DATA" if (si.Name.Len() > kPostfixSize + 1) si.Name.DeleteFrom(si.Name.Len() - kPostfixSize); Name += us2fs(si.Name); Size = si.Size; IsAltStream = true; return true; } } } } #endif CFindFile finder; #if defined(_WIN32) && !defined(UNDER_CE) { /* DWORD lastError = GetLastError(); if (lastError == ERROR_FILE_NOT_FOUND || lastError == ERROR_BAD_NETPATH // XP64: "\\Server\Share" || lastError == ERROR_BAD_NET_NAME // Win7: "\\Server\Share" || lastError == ERROR_INVALID_NAME // XP64: "\\?\UNC\Server\Share" || lastError == ERROR_BAD_PATHNAME // Win7: "\\?\UNC\Server\Share" ) */ unsigned rootSize = 0; if (IsSuperPath(path)) rootSize = kSuperPathPrefixSize; if (NName::IsDrivePath(path + rootSize) && path[rootSize + 3] == 0) { DWORD attrib = GetFileAttrib(path); if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) { ClearBase(); Attrib = attrib; Name = path + rootSize; Name.DeleteFrom(2); // we don't need backslash (C:) return true; } } else if (IS_PATH_SEPAR(path[0])) if (path[1] == 0) { DWORD attrib = GetFileAttrib(path); if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) { ClearBase(); Name.Empty(); Attrib = attrib; return true; } } else { const unsigned prefixSize = GetNetworkServerPrefixSize(path); if (prefixSize > 0 && path[prefixSize] != 0) { if (NName::FindSepar(path + prefixSize) < 0) { FString s = path; s.Add_PathSepar(); s += FCHAR_ANY_MASK; bool isOK = false; if (finder.FindFirst(s, *this)) { if (Name == FTEXT(".")) { Name = path + prefixSize; return true; } isOK = true; /* if "\\server\share" maps to root folder "d:\", there is no "." item. But it's possible that there are another items */ } { DWORD attrib = GetFileAttrib(path); if (isOK || attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) { ClearBase(); if (attrib != INVALID_FILE_ATTRIBUTES) Attrib = attrib; else SetAsDir(); Name = path + prefixSize; return true; } } // ::SetLastError(lastError); } } } } #endif return finder.FindFirst(path, *this); }
HRESULT CThreadCrc::ProcessVirt() { Hash.Init(); CMyBuffer buf; if (!buf.Allocate(kBufSize)) return E_OUTOFMEMORY; CProgressSync &sync = ProgressDialog.Sync; SetStatus(LangString(IDS_SCANNING)); Enumerator.Init(); FString path; NFind::CFileInfo fi; UInt64 numFiles = 0; UInt64 numItems = 0, numItems_Prev = 0; UInt64 totalSize = 0; for (;;) { bool filled; DWORD error = Enumerator.GetNextFile(fi, filled, path); if (error != 0) { AddErrorMessage(error, path); continue; } if (!filled) break; if (!fi.IsDir()) { totalSize += fi.Size; numFiles++; } numItems++; bool needPrint = false; // if (fi.IsDir()) { if (numItems - numItems_Prev >= 100) { needPrint = true; numItems_Prev = numItems; } } /* else if (numFiles - numFiles_Prev >= 200) { needPrint = true; numFiles_Prev = numFiles; } */ if (needPrint) { RINOK(sync.ScanProgress(numFiles, totalSize, path, fi.IsDir())); } } RINOK(sync.ScanProgress(numFiles, totalSize, FString(), false)); // sync.SetNumFilesTotal(numFiles); // sync.SetProgress(totalSize, 0); // SetStatus(LangString(IDS_CHECKSUM_CALCULATING)); // sync.SetCurFilePath(L""); SetStatus(L""); Enumerator.Init(); FString tempPath; FString firstFilePath; bool isFirstFile = true; UInt64 errorsFilesSize = 0; for (;;) { bool filled; DWORD error = Enumerator.GetNextFile(fi, filled, path); if (error != 0) { AddErrorMessage(error, path); continue; } if (!filled) break; error = 0; Hash.InitForNewFile(); if (!fi.IsDir()) { NIO::CInFile inFile; tempPath = Enumerator.BasePrefix_for_Open; tempPath += path; if (!inFile.Open(tempPath)) { error = GetNormalizedError(); AddErrorMessage(error, path); continue; } if (isFirstFile) { firstFilePath = path; isFirstFile = false; } sync.Set_FilePath(fs2us(path)); sync.Set_NumFilesCur(Hash.NumFiles); UInt64 progress_Prev = 0; for (;;) { UInt32 size; if (!inFile.Read(buf, kBufSize, size)) { error = GetNormalizedError(); AddErrorMessage(error, path); UInt64 errorSize = 0; if (inFile.GetLength(errorSize)) errorsFilesSize += errorSize; break; } if (size == 0) break; Hash.Update(buf, size); if (Hash.CurSize - progress_Prev >= ((UInt32)1 << 21)) { RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize + Hash.CurSize)); progress_Prev = Hash.CurSize; } } } if (error == 0) Hash.Final(fi.IsDir(), false, fs2us(path)); RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)); } RINOK(sync.Set_NumBytesCur(errorsFilesSize + Hash.FilesSize)); sync.Set_NumFilesCur(Hash.NumFiles); if (Hash.NumFiles != 1) sync.Set_FilePath(L""); SetStatus(L""); CProgressMessageBoxPair &pair = GetMessagePair(Hash.NumErrors != 0); AddHashBundleRes(pair.Message, Hash, fs2us(firstFilePath)); LangString(IDS_CHECKSUM_INFORMATION, pair.Title); return S_OK; }
HRESULT CThreadCrc::ProcessVirt() { DataSize = NumFolders = NumFiles = NumFilesScan = DataCrcSum = DataNameCrcSum = 0; memset(Sha256Sum, 0, SHA256_DIGEST_SIZE); // ProgressDialog.WaitCreating(); CMyBuffer bufferObject; if (!bufferObject.Allocate(kBufSize)) return E_OUTOFMEMORY; Byte *buffer = (Byte *)(void *)bufferObject; UInt64 totalSize = 0; Enumerator.Init(); UString scanningStr = LangString(IDS_SCANNING, 0x03020800); scanningStr += L' '; CProgressSync &sync = ProgressDialog.Sync; for (;;) { NFind::CFileInfo fileInfo; bool filled; FString resPath; HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath); if (errorCode != 0) { SetErrorPath1(resPath); return errorCode; } if (!filled) break; if (!fileInfo.IsDir()) { totalSize += fileInfo.Size; NumFilesScan++; } sync.SetCurrentFileName(scanningStr + fs2us(resPath)); sync.SetProgress(totalSize, 0); RINOK(sync.SetPosAndCheckPaused(0)); } sync.SetNumFilesTotal(NumFilesScan); sync.SetProgress(totalSize, 0); Enumerator.Init(); for (;;) { NFind::CFileInfo fileInfo; bool filled; FString resPath; HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath); if (errorCode != 0) { SetErrorPath1(resPath); return errorCode; } if (!filled) break; UInt32 crc = CRC_INIT_VAL; CSha256 sha256; Sha256_Init(&sha256); if (fileInfo.IsDir()) NumFolders++; else { NIO::CInFile inFile; if (!inFile.Open(Enumerator.BasePrefix + resPath)) { errorCode = GetNormalizedError(); SetErrorPath1(resPath); return errorCode; } sync.SetCurrentFileName(fs2us(resPath)); sync.SetNumFilesCur(NumFiles); NumFiles++; for (;;) { UInt32 processedSize; if (!inFile.Read(buffer, kBufSize, processedSize)) { errorCode = GetNormalizedError(); SetErrorPath1(resPath); return errorCode; } if (processedSize == 0) break; crc = CrcUpdate(crc, buffer, processedSize); if (NumFilesScan == 1) Sha256_Update(&sha256, buffer, processedSize); DataSize += processedSize; RINOK(sync.SetPosAndCheckPaused(DataSize)); } DataCrcSum += CRC_GET_DIGEST(crc); if (NumFilesScan == 1) Sha256_Final(&sha256, Sha256Sum); } for (int i = 0; i < resPath.Length(); i++) { wchar_t c = resPath[i]; crc = CRC_UPDATE_BYTE(crc, ((Byte)(c & 0xFF))); crc = CRC_UPDATE_BYTE(crc, ((Byte)((c >> 8) & 0xFF))); } DataNameCrcSum += CRC_GET_DIGEST(crc); RINOK(sync.SetPosAndCheckPaused(DataSize)); } sync.SetNumFilesCur(NumFiles); OkMessage = GetResultMessage(); OkMessageTitle = LangString(IDS_CHECKSUM_INFORMATION, 0x03020720); return S_OK; }
HRESULT CThreadSplit::ProcessVirt() { NIO::CInFile inFile; if (!inFile.Open(FilePath)) return GetLastError(); CPreAllocOutFile outFile; CMyBuffer buffer; if (!buffer.Allocate(kBufSize)) return E_OUTOFMEMORY; CVolSeqName seqName; seqName.SetNumDigits(NumVolumes); UInt64 length; if (!inFile.GetLength(length)) return GetLastError(); CProgressSync &sync = Sync; sync.Set_NumBytesTotal(length); UInt64 pos = 0; UInt64 prev = 0; UInt64 numFiles = 0; unsigned volIndex = 0; for (;;) { UInt64 volSize; if (volIndex < VolumeSizes.Size()) volSize = VolumeSizes[volIndex]; else volSize = VolumeSizes.Back(); UInt32 needSize = kBufSize; { const UInt64 rem = volSize - outFile.Written; if (needSize > rem) needSize = (UInt32)rem; } UInt32 processedSize; if (!inFile.Read(buffer, needSize, processedSize)) return GetLastError(); if (processedSize == 0) return S_OK; needSize = processedSize; if (outFile.Written == 0) { FString name = VolBasePath; name += '.'; name += us2fs(seqName.GetNextName()); sync.Set_FilePath(fs2us(name)); if (!outFile.File.Create(name, false)) { HRESULT res = GetLastError(); AddErrorPath(name); return res; } UInt64 expectSize = volSize; if (pos < length) { const UInt64 rem = length - pos; if (expectSize > rem) expectSize = rem; } outFile.PreAlloc(expectSize); } if (!outFile.Write(buffer, needSize, processedSize)) return GetLastError(); if (needSize != processedSize) throw g_Message_FileWriteError; pos += processedSize; if (outFile.Written == volSize) { outFile.Close(); sync.Set_NumFilesCur(++numFiles); if (volIndex < VolumeSizes.Size()) volIndex++; } if (pos - prev >= ((UInt32)1 << 22) || outFile.Written == 0) { RINOK(sync.Set_NumBytesCur(pos)); prev = pos; } } }
HRESULT CThreadSplit::ProcessVirt() { NIO::CInFile inFile; if (!inFile.Open(FilePath)) return GetLastError(); NIO::COutFile outFile; CMyBuffer bufferObject; if (!bufferObject.Allocate(kBufSize)) return E_OUTOFMEMORY; Byte *buffer = (Byte *)(void *)bufferObject; UInt64 curVolSize = 0; CVolSeqName seqName; seqName.SetNumDigits(NumVolumes); UInt64 length; if (!inFile.GetLength(length)) return GetLastError(); CProgressSync &sync = ProgressDialog.Sync; sync.Set_NumBytesTotal(length); UInt64 pos = 0; UInt64 numFiles = 0; unsigned volIndex = 0; for (;;) { UInt64 volSize; if (volIndex < VolumeSizes.Size()) volSize = VolumeSizes[volIndex]; else volSize = VolumeSizes.Back(); UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize)); UInt32 processedSize; if (!inFile.Read(buffer, needSize, processedSize)) return GetLastError(); if (processedSize == 0) break; needSize = processedSize; if (curVolSize == 0) { FString name = VolBasePath; name += FTEXT('.'); name += us2fs(seqName.GetNextName()); sync.Set_FilePath(fs2us(name)); sync.Set_NumFilesCur(numFiles++); if (!outFile.Create(name, false)) { HRESULT res = GetLastError(); AddErrorPath(name); return res; } } if (!outFile.Write(buffer, needSize, processedSize)) return GetLastError(); if (needSize != processedSize) throw g_Message_FileWriteError; curVolSize += processedSize; if (curVolSize == volSize) { outFile.Close(); if (volIndex < VolumeSizes.Size()) volIndex++; curVolSize = 0; } pos += processedSize; RINOK(sync.Set_NumBytesCur(pos)); } sync.Set_NumFilesCur(numFiles); return S_OK; }