diff -r 5f819b90d479 -r 99b265e0d1d0 misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.cpp --- a/misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.cpp Thu Oct 11 23:43:31 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,852 +0,0 @@ -// Update.cpp - -#include "StdAfx.h" - -#ifdef _WIN32 -#include -#endif - -#include "Update.h" - -#include "Common/IntToString.h" -#include "Common/StringConvert.h" -#include "Common/CommandLineParser.h" - -#ifdef _WIN32 -#include "Windows/DLL.h" -#endif - -#include "Windows/Defs.h" -#include "Windows/FileDir.h" -#include "Windows/FileFind.h" -#include "Windows/FileName.h" -#include "Windows/PropVariant.h" -#include "Windows/PropVariantConversions.h" -// #include "Windows/Synchronization.h" - -#include "../../Common/FileStreams.h" -#include "../../Compress/Copy/CopyCoder.h" - -#include "../Common/DirItem.h" -#include "../Common/EnumDirItems.h" -#include "../Common/UpdateProduce.h" -#include "../Common/OpenArchive.h" - -#include "TempFiles.h" -#include "UpdateCallback.h" -#include "EnumDirItems.h" -#include "SetProperties.h" - -static const char *kUpdateIsNotSupoorted = - "update operations are not supported for this archive"; - -using namespace NCommandLineParser; -using namespace NWindows; -using namespace NCOM; -using namespace NFile; -using namespace NName; - -static const wchar_t *kTempFolderPrefix = L"7zE"; - -using namespace NUpdateArchive; - -static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) -{ - CMyComPtr copyCoder = new NCompress::CCopyCoder; - return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); -} - -class COutMultiVolStream: - public IOutStream, - public CMyUnknownImp -{ - int _streamIndex; // required stream - UInt64 _offsetPos; // offset from start of _streamIndex index - UInt64 _absPos; - UInt64 _length; - - struct CSubStreamInfo - { - COutFileStream *StreamSpec; - CMyComPtr Stream; - UString Name; - UInt64 Pos; - UInt64 RealSize; - }; - CObjectVector Streams; -public: - // CMyComPtr VolumeCallback; - CRecordVector Sizes; - UString Prefix; - CTempFiles *TempFiles; - - void Init() - { - _streamIndex = 0; - _offsetPos = 0; - _absPos = 0; - _length = 0; - } - - HRESULT Close(); - - MY_UNKNOWN_IMP1(IOutStream) - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); - STDMETHOD(SetSize)(Int64 newSize); -}; - -// static NSynchronization::CCriticalSection g_TempPathsCS; - -HRESULT COutMultiVolStream::Close() -{ - HRESULT res = S_OK; - for (int i = 0; i < Streams.Size(); i++) - { - CSubStreamInfo &s = Streams[i]; - if (s.StreamSpec) - { - HRESULT res2 = s.StreamSpec->Close(); - if (res2 != S_OK) - res = res2; - } - } - return res; -} - -STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) -{ - if(processedSize != NULL) - *processedSize = 0; - while(size > 0) - { - if (_streamIndex >= Streams.Size()) - { - CSubStreamInfo subStream; - - wchar_t temp[32]; - ConvertUInt64ToString(_streamIndex + 1, temp); - UString res = temp; - while (res.Length() < 3) - res = UString(L'0') + res; - UString name = Prefix + res; - subStream.StreamSpec = new COutFileStream; - subStream.Stream = subStream.StreamSpec; - if(!subStream.StreamSpec->Create(name, false)) - return ::GetLastError(); - { - // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); - TempFiles->Paths.Add(name); - } - - subStream.Pos = 0; - subStream.RealSize = 0; - subStream.Name = name; - Streams.Add(subStream); - continue; - } - CSubStreamInfo &subStream = Streams[_streamIndex]; - - int index = _streamIndex; - if (index >= Sizes.Size()) - index = Sizes.Size() - 1; - UInt64 volSize = Sizes[index]; - - if (_offsetPos >= volSize) - { - _offsetPos -= volSize; - _streamIndex++; - continue; - } - if (_offsetPos != subStream.Pos) - { - // CMyComPtr outStream; - // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); - RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); - subStream.Pos = _offsetPos; - } - - UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos); - UInt32 realProcessed; - RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); - data = (void *)((Byte *)data + realProcessed); - size -= realProcessed; - subStream.Pos += realProcessed; - _offsetPos += realProcessed; - _absPos += realProcessed; - if (_absPos > _length) - _length = _absPos; - if (_offsetPos > subStream.RealSize) - subStream.RealSize = _offsetPos; - if(processedSize != NULL) - *processedSize += realProcessed; - if (subStream.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 = offset; - break; - case STREAM_SEEK_CUR: - _absPos += offset; - break; - case STREAM_SEEK_END: - _absPos = _length + offset; - break; - } - _offsetPos = _absPos; - if (newPosition != NULL) - *newPosition = _absPos; - _streamIndex = 0; - return S_OK; -} - -STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize) -{ - if (newSize < 0) - return E_INVALIDARG; - int i = 0; - while (i < Streams.Size()) - { - CSubStreamInfo &subStream = Streams[i++]; - if ((UInt64)newSize < subStream.RealSize) - { - RINOK(subStream.Stream->SetSize(newSize)); - subStream.RealSize = newSize; - break; - } - newSize -= subStream.RealSize; - } - while (i < Streams.Size()) - { - { - CSubStreamInfo &subStream = Streams.Back(); - subStream.Stream.Release(); - NDirectory::DeleteFileAlways(subStream.Name); - } - Streams.DeleteBack(); - } - _offsetPos = _absPos; - _streamIndex = 0; - _length = newSize; - return S_OK; -} - -static const wchar_t *kDefaultArchiveType = L"7z"; -static const wchar_t *kSFXExtension = - #ifdef _WIN32 - L"exe"; - #else - L""; - #endif - -bool CUpdateOptions::Init(const CCodecs *codecs, const UString &arcPath, const UString &arcType) -{ - if (!arcType.IsEmpty()) - MethodMode.FormatIndex = codecs->FindFormatForArchiveType(arcType); - else - { - MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath); - if (MethodMode.FormatIndex < 0) - MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType); - } - if (MethodMode.FormatIndex < 0) - return false; - const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex]; - UString typeExt = arcInfo.GetMainExt(); - UString ext = typeExt; - if (SfxMode) - ext = kSFXExtension; - ArchivePath.BaseExtension = ext; - ArchivePath.VolExtension = typeExt; - ArchivePath.ParseFromPath(arcPath); - for (int i = 0; i < Commands.Size(); i++) - { - CUpdateArchiveCommand &uc = Commands[i]; - uc.ArchivePath.BaseExtension = ext; - uc.ArchivePath.VolExtension = typeExt; - uc.ArchivePath.ParseFromPath(uc.UserArchivePath); - } - return true; -} - - -static HRESULT Compress( - CCodecs *codecs, - const CActionSet &actionSet, - IInArchive *archive, - const CCompressionMethodMode &compressionMethod, - CArchivePath &archivePath, - const CObjectVector &archiveItems, - bool shareForWrite, - bool stdInMode, - /* const UString & stdInFileName, */ - bool stdOutMode, - const CObjectVector &dirItems, - bool sfxMode, - const UString &sfxModule, - const CRecordVector &volumesSizes, - CTempFiles &tempFiles, - CUpdateErrorInfo &errorInfo, - IUpdateCallbackUI *callback) -{ - CMyComPtr outArchive; - if(archive != NULL) - { - CMyComPtr archive2 = archive; - HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); - if(result != S_OK) - throw kUpdateIsNotSupoorted; - } - else - { - RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive)); - - #ifdef EXTERNAL_CODECS - { - CMyComPtr setCompressCodecsInfo; - outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); - if (setCompressCodecsInfo) - { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); - } - } - #endif - } - if (outArchive == 0) - throw kUpdateIsNotSupoorted; - - NFileTimeType::EEnum fileTimeType; - UInt32 value; - RINOK(outArchive->GetFileTimeType(&value)); - - switch(value) - { - case NFileTimeType::kWindows: - case NFileTimeType::kDOS: - case NFileTimeType::kUnix: - fileTimeType = NFileTimeType::EEnum(value); - break; - default: - return E_FAIL; - } - - CObjectVector updatePairs; - GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!! - - CObjectVector updatePairs2; - UpdateProduce(updatePairs, actionSet, updatePairs2); - - UInt32 numFiles = 0; - for (int i = 0; i < updatePairs2.Size(); i++) - if (updatePairs2[i].NewData) - numFiles++; - - RINOK(callback->SetNumFiles(numFiles)); - - - CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; - CMyComPtr updateCallback(updateCallbackSpec); - - updateCallbackSpec->ShareForWrite = shareForWrite; - updateCallbackSpec->StdInMode = stdInMode; - updateCallbackSpec->Callback = callback; - updateCallbackSpec->DirItems = &dirItems; - updateCallbackSpec->ArchiveItems = &archiveItems; - updateCallbackSpec->UpdatePairs = &updatePairs2; - - CMyComPtr outStream; - - const UString &archiveName = archivePath.GetFinalPath(); - if (!stdOutMode) - { - UString resultPath; - int pos; - if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) - throw 1417161; - NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); - } - - COutFileStream *outStreamSpec = NULL; - COutMultiVolStream *volStreamSpec = NULL; - - if (volumesSizes.Size() == 0) - { - if (stdOutMode) - outStream = new CStdOutFileStream; - else - { - outStreamSpec = new COutFileStream; - outStream = outStreamSpec; - bool isOK = false; - UString realPath; - for (int i = 0; i < (1 << 16); i++) - { - if (archivePath.Temp) - { - if (i > 0) - { - wchar_t s[32]; - ConvertUInt64ToString(i, s); - archivePath.TempPostfix = s; - } - realPath = archivePath.GetTempPath(); - } - else - realPath = archivePath.GetFinalPath(); - if (outStreamSpec->Create(realPath, false)) - { - tempFiles.Paths.Add(realPath); - isOK = true; - break; - } - if (::GetLastError() != ERROR_FILE_EXISTS) - break; - if (!archivePath.Temp) - break; - } - if (!isOK) - { - errorInfo.SystemError = ::GetLastError(); - errorInfo.FileName = realPath; - errorInfo.Message = L"Can not open file"; - return E_FAIL; - } - } - } - else - { - if (stdOutMode) - return E_FAIL; - 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 sfxStream(sfxStreamSpec); - if (!sfxStreamSpec->Open(sfxModule)) - { - errorInfo.SystemError = ::GetLastError(); - errorInfo.Message = L"Can't open sfx module"; - errorInfo.FileName = sfxModule; - return E_FAIL; - } - - CMyComPtr sfxOutStream; - COutFileStream *outStreamSpec = NULL; - if (volumesSizes.Size() == 0) - sfxOutStream = outStream; - else - { - 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)); - if (outStreamSpec) - { - RINOK(outStreamSpec->Close()); - } - } - - HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback); - callback->Finilize(); - RINOK(result); - if (outStreamSpec) - result = outStreamSpec->Close(); - else if (volStreamSpec) - result = volStreamSpec->Close(); - return result; -} - -HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, - IInArchive *archive, - const UString &defaultItemName, - const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, - CObjectVector &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)); - ai.SizeIsDefined = (propertySize.vt != VT_EMPTY); - if (ai.SizeIsDefined) - ai.Size = ConvertPropVariantToUInt64(propertySize); - - ai.IndexInServer = i; - archiveItems.Add(ai); - } - return S_OK; -} - - -static HRESULT UpdateWithItemLists( - CCodecs *codecs, - CUpdateOptions &options, - IInArchive *archive, - const CObjectVector &archiveItems, - const CObjectVector &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( - codecs, - command.ActionSet, archive, - options.MethodMode, - command.ArchivePath, - archiveItems, - options.OpenShareForWrite, - options.StdInMode, - /* options.StdInFileName, */ - options.StdOutMode, - dirItems, - options.SfxMode, options.SfxModule, - options.VolumesSizes, - tempFiles, - errorInfo, callback)); - - RINOK(callback->FinishArchive()); - } - return S_OK; -} - -#ifdef _WIN32 -class CCurrentDirRestorer -{ - UString m_CurrentDirectory; -public: - CCurrentDirRestorer() - { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); } - ~CCurrentDirRestorer() - { RestoreDirectory();} - bool RestoreDirectory() - { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); } -}; -#endif - -struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback -{ - IUpdateCallbackUI2 *Callback; - HRESULT CheckBreak() { return Callback->CheckBreak(); } -}; - -HRESULT UpdateArchive( - CCodecs *codecs, - 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(codecs, archiveName, archiveLink, openCallback); - RINOK(callback->OpenResult(archiveName, result)); - RINOK(result); - if (archiveLink.VolumePaths.Size() > 1) - { - errorInfo.SystemError = (DWORD)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 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 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 archiveItems; - if (archive != NULL) - { - RINOK(EnumerateInArchiveItems(censor, - archive, defaultItemName, archiveFileInfo, archiveItems)); - } - - RINOK(UpdateWithItemLists(codecs, 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; -} -