diff options
author | 2023-12-06 07:58:49 +1100 | |
---|---|---|
committer | 2023-12-06 07:58:49 +1100 | |
commit | 79bef1e23049fdac25f1fefd132e0b6c7d2cc3a1 (patch) | |
tree | 643e9313fe86f583c4022c338677cbc12b761df7 /3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp | |
parent | 512ccf0c7c9b4f08e41038b2ed2de220e140385b (diff) |
3rdparty/lzma: Updated to version 23.01.
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp | 563 |
1 files changed, 278 insertions, 285 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp index 042991d196e..27625aebbe4 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/Update.cpp @@ -18,6 +18,8 @@ #include "../../Common/FileStreams.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/MultiOutStream.h" +#include "../../Common/StreamUtils.h" #include "../../Compress/CopyCoder.h" @@ -71,203 +73,44 @@ HRESULT CUpdateErrorInfo::SetFromError_DWORD(const char *message, const FString using namespace NUpdateArchive; -class COutMultiVolStream: - public IOutStream, - public CMyUnknownImp +struct CMultiOutStream_Rec { - unsigned _streamIndex; // required stream - UInt64 _offsetPos; // offset from start of _streamIndex index - UInt64 _absPos; - UInt64 _length; - - struct CAltStreamInfo - { - COutFileStream *StreamSpec; - CMyComPtr<IOutStream> Stream; - FString Name; - UInt64 Pos; - UInt64 RealSize; - }; - CObjectVector<CAltStreamInfo> Streams; -public: - // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; - CRecordVector<UInt64> Sizes; - FString Prefix; - CTempFiles *TempFiles; - - void Init() - { - _streamIndex = 0; - _offsetPos = 0; - _absPos = 0; - _length = 0; - } - - bool SetMTime(const CFiTime *mTime); - HRESULT Close(); - - UInt64 GetSize() const { return _length; } - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(UInt64 newSize); + CMultiOutStream *Spec; + CMyComPtr<IOutStream> Ref; }; -// static NSynchronization::CCriticalSection g_TempPathsCS; - -HRESULT COutMultiVolStream::Close() -{ - HRESULT res = S_OK; - FOR_VECTOR (i, Streams) - { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - { - HRESULT res2 = s->Close(); - if (res2 != S_OK) - res = res2; - } - } - return res; -} - -bool COutMultiVolStream::SetMTime(const CFiTime *mTime) -{ - bool res = true; - FOR_VECTOR (i, Streams) - { - COutFileStream *s = Streams[i].StreamSpec; - if (s) - if (!s->SetMTime(mTime)) - res = false; - } - return res; -} - -STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +struct CMultiOutStream_Bunch { - if (processedSize) - *processedSize = 0; - while (size > 0) + CObjectVector<CMultiOutStream_Rec> Items; + + HRESULT Destruct() { - if (_streamIndex >= Streams.Size()) + HRESULT hres = S_OK; + FOR_VECTOR (i, Items) { - CAltStreamInfo altStream; - - FString name; - name.Add_UInt32(_streamIndex + 1); - while (name.Len() < 3) - name.InsertAtFront(FTEXT('0')); - name.Insert(0, Prefix); - altStream.StreamSpec = new COutFileStream; - altStream.Stream = altStream.StreamSpec; - if (!altStream.StreamSpec->Create(name, false)) - return GetLastError_noZero_HRESULT(); + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) { - // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); - TempFiles->Paths.Add(name); + const HRESULT hres2 = rec.Spec->Destruct(); + if (hres == S_OK) + hres = hres2; } - - altStream.Pos = 0; - altStream.RealSize = 0; - altStream.Name = name; - Streams.Add(altStream); - continue; - } - CAltStreamInfo &altStream = Streams[_streamIndex]; - - unsigned index = _streamIndex; - if (index >= Sizes.Size()) - index = Sizes.Size() - 1; - UInt64 volSize = Sizes[index]; - - if (_offsetPos >= volSize) - { - _offsetPos -= volSize; - _streamIndex++; - continue; - } - if (_offsetPos != altStream.Pos) - { - // CMyComPtr<IOutStream> outStream; - // RINOK(altStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(altStream.Stream->Seek((Int64)_offsetPos, STREAM_SEEK_SET, NULL)); - altStream.Pos = _offsetPos; } - - UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - altStream.Pos); - UInt32 realProcessed; - RINOK(altStream.Stream->Write(data, curSize, &realProcessed)); - data = (const void *)((const Byte *)data + realProcessed); - size -= realProcessed; - altStream.Pos += realProcessed; - _offsetPos += realProcessed; - _absPos += realProcessed; - if (_absPos > _length) - _length = _absPos; - if (_offsetPos > altStream.RealSize) - altStream.RealSize = _offsetPos; - if (processedSize) - *processedSize += realProcessed; - if (altStream.Pos == volSize) - { - _streamIndex++; - _offsetPos = 0; - } - if (realProcessed == 0 && curSize != 0) - return E_FAIL; - break; - } - return S_OK; -} - -STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) -{ - if (seekOrigin >= 3) - return STG_E_INVALIDFUNCTION; - switch (seekOrigin) - { - case STREAM_SEEK_SET: _absPos = (UInt64)offset; break; - case STREAM_SEEK_CUR: _absPos = (UInt64)((Int64)_absPos + offset); break; - case STREAM_SEEK_END: _absPos = (UInt64)((Int64)_length + offset); break; + Items.Clear(); + return hres; } - _offsetPos = _absPos; - if (newPosition) - *newPosition = _absPos; - _streamIndex = 0; - return S_OK; -} -STDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize) -{ - unsigned i = 0; - while (i < Streams.Size()) + void DisableDeletion() { - CAltStreamInfo &altStream = Streams[i++]; - if ((UInt64)newSize < altStream.RealSize) + FOR_VECTOR (i, Items) { - RINOK(altStream.Stream->SetSize(newSize)); - altStream.RealSize = newSize; - break; + CMultiOutStream_Rec &rec = Items[i]; + if (rec.Ref) + rec.Spec->NeedDelete = false; } - newSize -= altStream.RealSize; } - while (i < Streams.Size()) - { - { - CAltStreamInfo &altStream = Streams.Back(); - altStream.Stream.Release(); - DeleteFileAlways(altStream.Name); - } - Streams.DeleteBack(); - } - _offsetPos = _absPos; - _streamIndex = 0; - _length = newSize; - return S_OK; -} +}; + void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) { @@ -305,7 +148,7 @@ UString CArchivePath::GetFinalPath() const UString path = GetPathWithoutExt(); if (!BaseExtension.IsEmpty()) { - path += '.'; + path.Add_Dot(); path += BaseExtension; } return path; @@ -317,7 +160,7 @@ UString CArchivePath::GetFinalVolPath() const // if BaseExtension is empty, we must ignore VolExtension also. if (!BaseExtension.IsEmpty()) { - path += '.'; + path.Add_Dot(); path += VolExtension; } return path; @@ -329,7 +172,7 @@ FString CArchivePath::GetTempPath() const path += us2fs(Name); if (!BaseExtension.IsEmpty()) { - path += '.'; + path.Add_Dot(); path += us2fs(BaseExtension); } path += ".tmp"; @@ -403,7 +246,7 @@ bool CUpdateOptions::SetArcPath(const CCodecs *codecs, const UString &arcPath) } -struct CUpdateProduceCallbackImp: public IUpdateProduceCallback +struct CUpdateProduceCallbackImp Z7_final: public IUpdateProduceCallback { const CObjectVector<CArcItem> *_arcItems; CDirItemsStat *_stat; @@ -417,7 +260,7 @@ struct CUpdateProduceCallbackImp: public IUpdateProduceCallback _stat(stat), _callback(callback) {} - virtual HRESULT ShowDeleteFile(unsigned arcIndex); + virtual HRESULT ShowDeleteFile(unsigned arcIndex) Z7_override; }; @@ -499,6 +342,8 @@ bool CRenamePair::GetNewPath(bool isFolder, const UString &src, UString &dest) c int FindAltStreamColon_in_Path(const wchar_t *path); #endif + + static HRESULT Compress( const CUpdateOptions &options, bool isUpdatingItself, @@ -511,6 +356,7 @@ static HRESULT Compress( const CDirItems &dirItems, const CDirItem *parentDirItem, CTempFiles &tempFiles, + CMultiOutStream_Bunch &multiStreams, CUpdateErrorInfo &errorInfo, IUpdateCallbackUI *callback, CFinishArchiveStat &st) @@ -530,15 +376,15 @@ static HRESULT Compress( } else { - RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)); + RINOK(codecs->CreateOutArchive((unsigned)formatIndex, outArchive)) - #ifdef EXTERNAL_CODECS + #ifdef Z7_EXTERNAL_CODECS { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)) } } #endif @@ -548,7 +394,7 @@ static HRESULT Compress( throw kUpdateIsNotSupoorted; // we need to set properties to get fileTimeType. - RINOK(SetProperties(outArchive, options.MethodMode.Properties)); + RINOK(SetProperties(outArchive, options.MethodMode.Properties)) NFileTimeType::EEnum fileTimeType; { @@ -580,7 +426,7 @@ static HRESULT Compress( */ UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); + RINOK(outArchive->GetFileTimeType(&value)) // we support any future fileType here. fileTimeType = (NFileTimeType::EEnum)value; @@ -676,7 +522,7 @@ static HRESULT Compress( if (needRename) { up2.NewProps = true; - RINOK(arc->IsItem_Anti(i, up2.IsAnti)); + RINOK(arc->IsItem_Anti(i, up2.IsAnti)) up2.NewNameIndex = (int)newNames.Add(dest); } updatePairs2.Add(up2); @@ -768,7 +614,7 @@ static HRESULT Compress( } } } - RINOK(callback->SetNumItems(stat2)); + RINOK(callback->SetNumItems(stat2)) } CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; @@ -828,7 +674,7 @@ static HRESULT Compress( COutFileStream *outStreamSpec = NULL; CStdOutFileStream *stdOutFileStreamSpec = NULL; - COutMultiVolStream *volStreamSpec = NULL; + CMultiOutStream *volStreamSpec = NULL; if (options.VolumesSizes.Size() == 0) { @@ -881,14 +727,17 @@ static HRESULT Compress( if (arc && arc->GetGlobalOffset() > 0) return E_NOTIMPL; - volStreamSpec = new COutMultiVolStream; + volStreamSpec = new CMultiOutStream(); outSeekStream = volStreamSpec; outStream = outSeekStream; - volStreamSpec->Sizes = options.VolumesSizes; volStreamSpec->Prefix = us2fs(archivePath.GetFinalVolPath()); - volStreamSpec->Prefix += '.'; - volStreamSpec->TempFiles = &tempFiles; - volStreamSpec->Init(); + volStreamSpec->Prefix.Add_Dot(); + volStreamSpec->Init(options.VolumesSizes); + { + CMultiOutStream_Rec &rec = multiStreams.Items.AddNew(); + rec.Spec = volStreamSpec; + rec.Ref = rec.Spec; + } /* updateCallbackSpec->VolumesSizes = volumesSizes; @@ -913,22 +762,22 @@ static HRESULT Compress( { outStreamSpec2 = new COutFileStream; sfxOutStream = outStreamSpec2; - FString realPath = us2fs(archivePath.GetFinalPath()); + const FString realPath = us2fs(archivePath.GetFinalPath()); if (!outStreamSpec2->Create(realPath, false)) return errorInfo.SetFromLastError("cannot open file", realPath); } { UInt64 sfxSize; - RINOK(sfxStreamSpec->GetSize(&sfxSize)); - RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)); + RINOK(sfxStreamSpec->GetSize(&sfxSize)) + RINOK(callback->WriteSfx(fs2us(options.SfxModule), sfxSize)) } - RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)); + RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)) if (outStreamSpec2) { - RINOK(outStreamSpec2->Close()); + RINOK(outStreamSpec2->Close()) } } @@ -939,8 +788,8 @@ static HRESULT Compress( else { // Int64 globalOffset = arc->GetGlobalOffset(); - RINOK(arc->InStream->Seek(0, STREAM_SEEK_SET, NULL)); - RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)); + RINOK(InStream_SeekToBegin(arc->InStream)) + RINOK(NCompress::CopyStream_ExactSize(arc->InStream, outStream, arc->ArcStreamOffset, NULL)) if (options.StdOutMode) tailStream = outStream; else @@ -953,10 +802,57 @@ static HRESULT Compress( } } + CFiTime ft; + FiTime_Clear(ft); + bool ft_Defined = false; + { + FOR_VECTOR (i, updatePairs2) + { + const CUpdatePair2 &pair2 = updatePairs2[i]; + CFiTime ft2; + FiTime_Clear(ft2); + bool ft2_Defined = false; + /* we use full precision of dirItem, if dirItem is defined + and (dirItem will be used or dirItem is sameTime in dir and arc */ + if (pair2.DirIndex >= 0 && + (pair2.NewProps || pair2.IsSameTime)) + { + ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; + ft2_Defined = true; + } + else if (pair2.UseArcProps && pair2.ArcIndex >= 0) + { + const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; + if (arcItem.MTime.Def) + { + arcItem.MTime.Write_To_FiTime(ft2); + ft2_Defined = true; + } + } + if (ft2_Defined) + { + if (!ft_Defined || Compare_FiTime(&ft, &ft2) < 0) + { + ft = ft2; + ft_Defined = true; + } + } + } + /* + if (fileTimeType != NFileTimeType::kNotDefined) + FiTime_Normalize_With_Prec(ft, fileTimeType); + */ + } + + if (volStreamSpec && options.SetArcMTime && ft_Defined) + { + volStreamSpec->MTime = ft; + volStreamSpec->MTime_Defined = true; + } HRESULT result = outArchive->UpdateItems(tailStream, updatePairs2.Size(), updateCallback); // callback->Finalize(); - RINOK(result); + RINOK(result) if (!updateCallbackSpec->AreAllFilesClosed()) { @@ -967,10 +863,6 @@ static HRESULT Compress( if (options.SetArcMTime) { - CFiTime ft; - FiTime_Clear(ft); - bool isDefined = false; - // bool needNormalizeAfterStream; // needParse; /* @@ -990,40 +882,9 @@ static HRESULT Compress( // CArcTime at = StreamCallback_ArcMTime; // updateCallbackSpec->StreamCallback_ArcMTime.Write_To_FiTime(ft); // we must normalize with precision from archive; - ft = updateCallbackSpec->LatestMTime; - isDefined = true; - } - - FOR_VECTOR (i, updatePairs2) - { - const CUpdatePair2 &pair2 = updatePairs2[i]; - CFiTime ft2; - bool ft2_Defined = false; - /* we use full precision of dirItem, if dirItem is defined - and (dirItem will be used or dirItem is sameTime in dir and arc */ - if (pair2.DirIndex >= 0 && - (pair2.NewProps || pair2.IsSameTime)) - { - ft2 = dirItems.Items[(unsigned)pair2.DirIndex].MTime; - ft2_Defined = true; - } - else if (pair2.UseArcProps && pair2.ArcIndex >= 0) - { - const CArcItem &arcItem = arcItems[(unsigned)pair2.ArcIndex]; - if (arcItem.MTime.Def) - { - arcItem.MTime.Write_To_FiTime(ft2); - ft2_Defined = true; - } - } - if (ft2_Defined) - { - if (Compare_FiTime(&ft, &ft2) < 0) - { - ft = ft2; - isDefined = true; - } - } + if (!ft_Defined || Compare_FiTime(&ft, &updateCallbackSpec->LatestMTime) < 0) + ft = updateCallbackSpec->LatestMTime; + ft_Defined = true; } /* if (fileTimeType != NFileTimeType::kNotDefined) @@ -1031,12 +892,14 @@ static HRESULT Compress( */ } // if (ft.dwLowDateTime != 0 || ft.dwHighDateTime != 0) - if (isDefined) + if (ft_Defined) { + // we ignore set time errors here. + // note that user could move some finished volumes to another folder. if (outStreamSpec) outStreamSpec->SetMTime(&ft); else if (volStreamSpec) - volStreamSpec->SetMTime(&ft); + volStreamSpec->SetMTime_Final(ft); } } @@ -1056,7 +919,10 @@ static HRESULT Compress( if (outStreamSpec) result = outStreamSpec->Close(); else if (volStreamSpec) - result = volStreamSpec->Close(); + { + result = volStreamSpec->FinalFlush_and_CloseFiles(st.NumVolumes); + st.IsMultiVolMode = true; + } RINOK(result) @@ -1121,7 +987,7 @@ static HRESULT EnumerateInArchiveItems( arcItems.Clear(); UInt32 numItems; IInArchive *archive = arc.Archive; - RINOK(archive->GetNumberOfItems(&numItems)); + RINOK(archive->GetNumberOfItems(&numItems)) arcItems.ClearAndReserve(numItems); CReadArcItem item; @@ -1132,7 +998,7 @@ static HRESULT EnumerateInArchiveItems( { CArcItem ai; - RINOK(arc.GetItem(i, item)); + RINOK(arc.GetItem(i, item)) ai.Name = item.Path; ai.IsDir = item.IsDir; ai.IsAltStream = @@ -1152,8 +1018,8 @@ static HRESULT EnumerateInArchiveItems( ai.Censored = Censor_CheckPath(censor, item); // ai.MTime will be set to archive MTime, if not present in archive item - RINOK(arc.GetItem_MTime(i, ai.MTime)); - RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)); + RINOK(arc.GetItem_MTime(i, ai.MTime)) + RINOK(arc.GetItem_Size(i, ai.Size, ai.Size_Defined)) ai.IndexInServer = i; arcItems.AddInReserved(ai); @@ -1163,10 +1029,73 @@ static HRESULT EnumerateInArchiveItems( #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(__MINGW32__) || defined(__MINGW64__) +#include <mapi.h> +#else #include <MAPI.h> - #endif +extern "C" { + +#ifdef MAPI_FORCE_UNICODE + +#define Z7_WIN_LPMAPISENDMAILW LPMAPISENDMAILW +#define Z7_WIN_MapiFileDescW MapiFileDescW +#define Z7_WIN_MapiMessageW MapiMessageW +#define Z7_WIN_MapiRecipDescW MapiRecipDescW + +#else + +typedef struct +{ + ULONG ulReserved; + ULONG ulRecipClass; + PWSTR lpszName; + PWSTR lpszAddress; + ULONG ulEIDSize; + PVOID lpEntryID; +} Z7_WIN_MapiRecipDescW, *Z7_WIN_lpMapiRecipDescW; + +typedef struct +{ + ULONG ulReserved; + ULONG flFlags; + ULONG nPosition; + PWSTR lpszPathName; + PWSTR lpszFileName; + PVOID lpFileType; +} Z7_WIN_MapiFileDescW, *Z7_WIN_lpMapiFileDescW; + +typedef struct +{ + ULONG ulReserved; + PWSTR lpszSubject; + PWSTR lpszNoteText; + PWSTR lpszMessageType; + PWSTR lpszDateReceived; + PWSTR lpszConversationID; + FLAGS flFlags; + Z7_WIN_lpMapiRecipDescW lpOriginator; + ULONG nRecipCount; + Z7_WIN_lpMapiRecipDescW lpRecips; + ULONG nFileCount; + Z7_WIN_lpMapiFileDescW lpFiles; +} Z7_WIN_MapiMessageW, *Z7_WIN_lpMapiMessageW; + +typedef ULONG (FAR PASCAL Z7_WIN_MAPISENDMAILW)( + LHANDLE lhSession, + ULONG_PTR ulUIParam, + Z7_WIN_lpMapiMessageW lpMessage, + FLAGS flFlags, + ULONG ulReserved +); +typedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW; + +#endif // MAPI_FORCE_UNICODE +} +#endif // _WIN32 + + HRESULT UpdateArchive( CCodecs *codecs, const CObjectVector<COpenType> &types, @@ -1253,8 +1182,7 @@ HRESULT UpdateArchive( if (!options.VolumesSizes.IsEmpty()) { arcPath = options.ArchivePath.GetFinalVolPath(); - arcPath += '.'; - arcPath += "001"; + arcPath += ".001"; } if (cmdArcPath2.IsEmpty()) @@ -1268,7 +1196,7 @@ HRESULT UpdateArchive( if (!fi.Find_FollowLink(us2fs(arcPath))) { if (renameMode) - throw "can't find archive";; + throw "can't find archive"; if (options.MethodMode.Type.FormatIndex < 0) { if (!options.SetArcPath(codecs, cmdArcPath2)) @@ -1319,7 +1247,7 @@ HRESULT UpdateArchive( CIntVector excl; COpenOptions op; - #ifndef _SFX + #ifndef Z7_SFX op.props = &options.MethodMode.Properties; #endif op.codecs = codecs; @@ -1329,7 +1257,7 @@ HRESULT UpdateArchive( op.stream = NULL; op.filePath = arcPath; - RINOK(callback->StartOpenArchive(arcPath)); + RINOK(callback->StartOpenArchive(arcPath)) HRESULT result = arcLink.Open_Strict(op, openCallback); @@ -1341,8 +1269,8 @@ HRESULT UpdateArchive( if (result == S_FALSE) return E_FAIL; */ - RINOK(res2); - RINOK(result); + RINOK(res2) + RINOK(result) if (arcLink.VolumePaths.Size() > 1) { @@ -1422,7 +1350,7 @@ HRESULT UpdateArchive( if (needScanning) { - RINOK(callback->StartScanning()); + RINOK(callback->StartScanning()) dirItems.SymLinks = options.SymLinks.Val; @@ -1452,7 +1380,7 @@ HRESULT UpdateArchive( return res; } - RINOK(callback->FinishScanning(dirItems.Stat)); + RINOK(callback->FinishScanning(dirItems.Stat)) // 22.00: we don't need parent folder, if absolute path mode if (options.PathMode != NWildcard::k_AbsPath) @@ -1460,7 +1388,7 @@ HRESULT UpdateArchive( { NFind::CFileInfo fi; FString prefix = us2fs(censor.Pairs[0].Prefix); - prefix += '.'; + prefix.Add_Dot(); // UString prefix = censor.Pairs[0].Prefix; /* if (prefix.Back() == WCHAR_PATH_SEPARATOR) @@ -1576,7 +1504,7 @@ HRESULT UpdateArchive( { RINOK(EnumerateInArchiveItems( // options.StoreAltStreams, - censor, arcLink.Arcs.Back(), arcItems)); + censor, arcLink.Arcs.Back(), arcItems)) } /* @@ -1595,8 +1523,10 @@ HRESULT UpdateArchive( processedItems[i] = 0; } + CMultiOutStream_Bunch multiStreams; + /* - #ifndef _NO_CRYPTO + #ifndef Z7_NO_CRYPTO if (arcLink.PasswordWasAsked) { // We set password, if open have requested password @@ -1640,18 +1570,22 @@ HRESULT UpdateArchive( parentDirItem_Ptr, tempFiles, - errorInfo, callback, st)); + multiStreams, + errorInfo, callback, st)) - RINOK(callback->FinishArchive(st)); + RINOK(callback->FinishArchive(st)) } if (thereIsInArchive) { - RINOK(arcLink.Close()); + RINOK(arcLink.Close()) arcLink.Release(); } + multiStreams.DisableDeletion(); + RINOK(multiStreams.Destruct()) + tempFiles.Paths.Clear(); if (createTempFile) { @@ -1702,6 +1636,19 @@ HRESULT UpdateArchive( return errorInfo.Get_HRESULT_Error(); } + FStringVector fullPaths; + unsigned i; + + for (i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + const FString finalPath = us2fs(ap.GetFinalPath()); + FString arcPath2; + if (!MyGetFullPathName(finalPath, arcPath2)) + return errorInfo.SetFromLastError("GetFullPathName error", finalPath); + fullPaths.Add(arcPath2); + } + /* LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); if (fnSend == 0) @@ -1710,25 +1657,70 @@ HRESULT UpdateArchive( return errorInfo.Get_HRESULT_Error(); } */ + const + Z7_WIN_LPMAPISENDMAILW sendMailW = Z7_GET_PROC_ADDRESS( + Z7_WIN_LPMAPISENDMAILW, mapiLib.Get_HMODULE(), + "MAPISendMailW"); + if (sendMailW) + { + + CCurrentDirRestorer curDirRestorer; + + UStringVector paths; + UStringVector names; - LPMAPISENDMAIL sendMail = (LPMAPISENDMAIL)(void *)mapiLib.GetProc("MAPISendMail"); - if (sendMail == 0) + for (i = 0; i < fullPaths.Size(); i++) { - errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); - return errorInfo.Get_HRESULT_Error();; + const UString arcPath2 = fs2us(fullPaths[i]); + const UString fileName = ExtractFileNameFromPath(arcPath2); + paths.Add(arcPath2); + names.Add(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); } - FStringVector fullPaths; - unsigned i; + CRecordVector<Z7_WIN_MapiFileDescW> files; + files.ClearAndSetSize(paths.Size()); - for (i = 0; i < options.Commands.Size(); i++) + for (i = 0; i < paths.Size(); i++) { - CArchivePath &ap = options.Commands[i].ArchivePath; - FString finalPath = us2fs(ap.GetFinalPath()); - FString arcPath2; - if (!MyGetFullPathName(finalPath, arcPath2)) - return errorInfo.SetFromLastError("GetFullPathName error", finalPath); - fullPaths.Add(arcPath2); + Z7_WIN_MapiFileDescW &f = files[i]; + memset(&f, 0, sizeof(f)); + f.nPosition = 0xFFFFFFFF; + f.lpszPathName = paths[i].Ptr_non_const(); + f.lpszFileName = names[i].Ptr_non_const(); + } + + { + Z7_WIN_MapiMessageW m; + memset(&m, 0, sizeof(m)); + m.nFileCount = files.Size(); + m.lpFiles = &files.Front(); + + const UString addr (options.EMailAddress); + Z7_WIN_MapiRecipDescW rec; + if (!addr.IsEmpty()) + { + memset(&rec, 0, sizeof(rec)); + rec.ulRecipClass = MAPI_TO; + rec.lpszAddress = addr.Ptr_non_const(); + m.nRecipCount = 1; + m.lpRecips = &rec; + } + + sendMailW((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); + } + } + else + { + const + LPMAPISENDMAIL sendMail = Z7_GET_PROC_ADDRESS( + LPMAPISENDMAIL, mapiLib.Get_HMODULE(), + "MAPISendMail"); + if (!sendMail) + { + errorInfo.SetFromLastError("7-Zip cannot find MAPISendMail function"); + return errorInfo.Get_HRESULT_Error(); } CCurrentDirRestorer curDirRestorer; @@ -1779,6 +1771,7 @@ HRESULT UpdateArchive( sendMail((LHANDLE)0, 0, &m, MAPI_DIALOG, 0); } + } } #endif @@ -1827,7 +1820,7 @@ HRESULT UpdateArchive( && Compare_FiTime(&fileInfo.MTime, &dirItem.MTime) == 0 && Compare_FiTime(&fileInfo.CTime, &dirItem.CTime) == 0) { - RINOK(callback->DeletingAfterArchiving(phyPath, false)); + RINOK(callback->DeletingAfterArchiving(phyPath, false)) DeleteFileAlways(phyPath); } } @@ -1852,12 +1845,12 @@ HRESULT UpdateArchive( const FString phyPath = dirItems.GetPhyPath(pairs[i].Index); if (NFind::DoesDirExist(phyPath)) { - RINOK(callback->DeletingAfterArchiving(phyPath, true)); + RINOK(callback->DeletingAfterArchiving(phyPath, true)) RemoveDir(phyPath); } } - RINOK(callback->FinishDeletingAfterArchiving()); + RINOK(callback->FinishDeletingAfterArchiving()) } return S_OK; |