📄 update.cpp
字号:
} else { if (stdOutMode) return E_FAIL; COutMultiVolStream *volStreamSpec = new COutMultiVolStream; outStream = volStreamSpec; volStreamSpec->Sizes = volumesSizes; volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L"."); volStreamSpec->TempFiles = &tempFiles; volStreamSpec->Init(); /* updateCallbackSpec->VolumesSizes = volumesSizes; updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; if (!archivePath.VolExtension.IsEmpty()) updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; */ } RINOK(SetProperties(outArchive, compressionMethod.Properties)); if (sfxMode) { CInFileStream *sfxStreamSpec = new CInFileStream; CMyComPtr<IInStream> sfxStream(sfxStreamSpec); if (!sfxStreamSpec->Open(sfxModule)) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"Can't open sfx module"; errorInfo.FileName = sfxModule; return E_FAIL; } CMyComPtr<ISequentialOutStream> sfxOutStream; if (volumesSizes.Size() == 0) sfxOutStream = outStream; else { COutFileStream *outStreamSpec = new COutFileStream; sfxOutStream = outStreamSpec; UString realPath = archivePath.GetFinalPath(); if (!outStreamSpec->Create(realPath, false)) { errorInfo.SystemError = ::GetLastError(); errorInfo.FileName = realPath; errorInfo.Message = L"Can not open file"; return E_FAIL; } } RINOK(CopyBlock(sfxStream, sfxOutStream)); } HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback); callback->Finilize(); return result;}HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, IInArchive *archive, const UString &defaultItemName, const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, CObjectVector<CArchiveItem> &archiveItems){ archiveItems.Clear(); UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); archiveItems.Reserve(numItems); for(UInt32 i = 0; i < numItems; i++) { CArchiveItem ai; RINOK(GetArchiveItemPath(archive, i, ai.Name)); RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory)); ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory); RINOK(GetArchiveItemFileTime(archive, i, archiveFileInfo.LastWriteTime, ai.LastWriteTime)); CPropVariant propertySize; RINOK(archive->GetProperty(i, kpidSize, &propertySize)); if (ai.SizeIsDefined = (propertySize.vt != VT_EMPTY)) ai.Size = ConvertPropVariantToUInt64(propertySize); ai.IndexInServer = i; archiveItems.Add(ai); } return S_OK;}static HRESULT UpdateWithItemLists( CUpdateOptions &options, IInArchive *archive, const CObjectVector<CArchiveItem> &archiveItems, const CObjectVector<CDirItem> &dirItems, CTempFiles &tempFiles, CUpdateErrorInfo &errorInfo, IUpdateCallbackUI2 *callback){ for(int i = 0; i < options.Commands.Size(); i++) { CUpdateArchiveCommand &command = options.Commands[i]; if (options.StdOutMode) { RINOK(callback->StartArchive(0, archive != 0)); } else { RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), i == 0 && options.UpdateArchiveItself && archive != 0)); } RINOK(Compress(command.ActionSet, archive, options.MethodMode, command.ArchivePath, archiveItems, options.StdInMode, options.StdInFileName, options.StdOutMode, dirItems, options.SfxMode, options.SfxModule, options.VolumesSizes, tempFiles, errorInfo, callback)); RINOK(callback->FinishArchive()); } return S_OK;}#ifdef _WIN32class CCurrentDirRestorer{ UString m_CurrentDirectory;public: CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); } ~CCurrentDirRestorer() { RestoreDirectory();} bool RestoreDirectory() { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); }};#endifstruct CEnumDirItemUpdateCallback: public IEnumDirItemCallback{ IUpdateCallbackUI2 *Callback; HRESULT CheckBreak() { return Callback->CheckBreak(); }};HRESULT UpdateArchive(const NWildcard::CCensor &censor, CUpdateOptions &options, CUpdateErrorInfo &errorInfo, IOpenCallbackUI *openCallback, IUpdateCallbackUI2 *callback){ if (options.StdOutMode && options.EMailMode) return E_FAIL; if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode)) return E_NOTIMPL; if (options.SfxMode) { CProperty property; property.Name = L"rsfx"; property.Value = L"on"; options.MethodMode.Properties.Add(property); if (options.SfxModule.IsEmpty()) { errorInfo.Message = L"sfx file is not specified"; return E_FAIL; } UString name = options.SfxModule; if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule)) { errorInfo.Message = L"can't find specified sfx module"; return E_FAIL; } } const UString archiveName = options.ArchivePath.GetFinalPath(); UString defaultItemName; NFind::CFileInfoW archiveFileInfo; CArchiveLink archiveLink; IInArchive *archive = 0; if (NFind::FindFile(archiveName, archiveFileInfo)) { if (archiveFileInfo.IsDirectory()) throw "there is no such archive"; if (options.VolumesSizes.Size() > 0) return E_NOTIMPL; HRESULT result = MyOpenArchive(archiveName, archiveLink, openCallback); RINOK(callback->OpenResult(archiveName, result)); RINOK(result); if (archiveLink.VolumePaths.Size() > 1) { errorInfo.SystemError = E_NOTIMPL; errorInfo.Message = L"Updating for multivolume archives is not implemented"; return E_NOTIMPL; } archive = archiveLink.GetArchive(); defaultItemName = archiveLink.GetDefaultItemName(); } else { /* if (archiveType.IsEmpty()) throw "type of archive is not specified"; */ } CObjectVector<CDirItem> dirItems; if (options.StdInMode) { CDirItem item; item.FullPath = item.Name = options.StdInFileName; item.Size = (UInt64)(Int64)-1; item.Attributes = 0; SYSTEMTIME st; FILETIME ft; GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft; dirItems.Add(item); } else { bool needScanning = false; for(int i = 0; i < options.Commands.Size(); i++) if (options.Commands[i].ActionSet.NeedScanning()) needScanning = true; if (needScanning) { CEnumDirItemUpdateCallback enumCallback; enumCallback.Callback = callback; RINOK(callback->StartScanning()); UStringVector errorPaths; CRecordVector<DWORD> errorCodes; HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes); for (int i = 0; i < errorPaths.Size(); i++) { RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i])); } if(res != S_OK) { errorInfo.Message = L"Scanning error"; // errorInfo.FileName = errorPath; return res; } RINOK(callback->FinishScanning()); } } UString tempDirPrefix; bool usesTempDir = false; #ifdef _WIN32 NDirectory::CTempDirectoryW tempDirectory; if (options.EMailMode && options.EMailRemoveAfter) { tempDirectory.Create(kTempFolderPrefix); tempDirPrefix = tempDirectory.GetPath(); NormalizeDirPathPrefix(tempDirPrefix); usesTempDir = true; } #endif CTempFiles tempFiles; bool createTempFile = false; if(!options.StdOutMode && options.UpdateArchiveItself) { CArchivePath &ap = options.Commands[0].ArchivePath; ap = options.ArchivePath; // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) { createTempFile = true; ap.Temp = true; if (!options.WorkingDir.IsEmpty()) { ap.TempPrefix = options.WorkingDir; NormalizeDirPathPrefix(ap.TempPrefix); } } } for(int i = 0; i < options.Commands.Size(); i++) { CArchivePath &ap = options.Commands[i].ArchivePath; if (usesTempDir) { // Check it ap.Prefix = tempDirPrefix; // ap.Temp = true; // ap.TempPrefix = tempDirPrefix; } if (i > 0 || !createTempFile) { const UString &path = ap.GetFinalPath(); if (NFind::DoesFileExist(path)) { errorInfo.SystemError = 0; errorInfo.Message = L"File already exists"; errorInfo.FileName = path; return E_FAIL; } } } CObjectVector<CArchiveItem> archiveItems; if (archive != NULL) { RINOK(EnumerateInArchiveItems(censor, archive, defaultItemName, archiveFileInfo, archiveItems)); } RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, tempFiles, errorInfo, callback)); if (archive != NULL) { RINOK(archiveLink.Close()); archiveLink.Release(); } tempFiles.Paths.Clear(); if(createTempFile) { try { CArchivePath &ap = options.Commands[0].ArchivePath; const UString &tempPath = ap.GetTempPath(); if (archive != NULL) if (!NDirectory::DeleteFileAlways(archiveName)) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"delete file error"; errorInfo.FileName = archiveName; return E_FAIL; } if (!NDirectory::MyMoveFile(tempPath, archiveName)) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"move file error"; errorInfo.FileName = tempPath; errorInfo.FileName2 = archiveName; return E_FAIL; } } catch(...) { throw; } } #ifdef _WIN32 if (options.EMailMode) { NDLL::CLibrary mapiLib; if (!mapiLib.Load(TEXT("Mapi32.dll"))) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"can not load Mapi32.dll"; return E_FAIL; } LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS) mapiLib.GetProcAddress("MAPISendDocuments"); if (fnSend == 0) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = L"can not find MAPISendDocuments function"; return E_FAIL; } UStringVector fullPaths; int i; for(i = 0; i < options.Commands.Size(); i++) { CArchivePath &ap = options.Commands[i].ArchivePath; UString arcPath; if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath)) { errorInfo.SystemError = ::GetLastError(); return E_FAIL; } fullPaths.Add(arcPath); } CCurrentDirRestorer curDirRestorer; for(i = 0; i < fullPaths.Size(); i++) { UString arcPath = fullPaths[i]; UString fileName = ExtractFileNameFromPath(arcPath); AString path = GetAnsiString(arcPath); AString name = GetAnsiString(fileName); // Warning!!! MAPISendDocuments function changes Current directory fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); } } #endif return S_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -