1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Update.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Update.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/IntToString.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/StringConvert.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _WIN32 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/DLL.h" 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileDir.h" 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileFind.h" 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/FileName.h" 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariant.h" 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariantConversions.h" 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/Time.h" 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/FileStreams.h" 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Compress/CopyCoder.h" 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/DirItem.h" 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/EnumDirItems.h" 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/OpenArchive.h" 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/UpdateProduce.h" 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "EnumDirItems.h" 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "SetProperties.h" 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "TempFiles.h" 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "UpdateCallback.h" 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 35baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kUpdateIsNotSupoorted = 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync "update operations are not supported for this archive"; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 38baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NCOM; 40baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NFile; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NName; 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kTempFolderPrefix = L"7zE"; 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 45baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NUpdateArchive; 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass COutMultiVolStream: 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public IOutStream, 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public CMyUnknownImp 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int _streamIndex; // required stream 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 _offsetPos; // offset from start of _streamIndex index 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 _absPos; 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 _length; 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync struct CSubStreamInfo 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COutFileStream *StreamSpec; 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IOutStream> Stream; 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString Name; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 Pos; 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 RealSize; 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync }; 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CSubStreamInfo> Streams; 65baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> Sizes; 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString Prefix; 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTempFiles *TempFiles; 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Init() 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamIndex = 0; 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _offsetPos = 0; 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _absPos = 0; 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _length = 0; 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT Close(); 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_UNKNOWN_IMP1(IOutStream) 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync STDMETHOD(SetSize)(UInt64 newSize); 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// static NSynchronization::CCriticalSection g_TempPathsCS; 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 90baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutMultiVolStream::Close() 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res = S_OK; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < Streams.Size(); i++) 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSubStreamInfo &s = Streams[i]; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (s.StreamSpec) 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res2 = s.StreamSpec->Close(); 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res2 != S_OK) 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = res2; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 106baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedSize != NULL) 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = 0; 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while(size > 0) 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_streamIndex >= Streams.Size()) 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSubStreamInfo subStream; 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t temp[16]; 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ConvertUInt32ToString(_streamIndex + 1, temp); 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString res = temp; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (res.Length() < 3) 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync res = UString(L'0') + res; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString name = Prefix + res; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.StreamSpec = new COutFileStream; 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.Stream = subStream.StreamSpec; 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!subStream.StreamSpec->Create(name, false)) 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ::GetLastError(); 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync TempFiles->Paths.Add(name); 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.Pos = 0; 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.RealSize = 0; 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.Name = name; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Streams.Add(subStream); 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSubStreamInfo &subStream = Streams[_streamIndex]; 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = _streamIndex; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index >= Sizes.Size()) 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync index = Sizes.Size() - 1; 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 volSize = Sizes[index]; 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_offsetPos >= volSize) 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _offsetPos -= volSize; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamIndex++; 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_offsetPos != subStream.Pos) 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // CMyComPtr<IOutStream> outStream; 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.Pos = _offsetPos; 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos); 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 realProcessed; 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync data = (void *)((Byte *)data + realProcessed); 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size -= realProcessed; 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.Pos += realProcessed; 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _offsetPos += realProcessed; 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _absPos += realProcessed; 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_absPos > _length) 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _length = _absPos; 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_offsetPos > subStream.RealSize) 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.RealSize = _offsetPos; 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedSize != NULL) 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize += realProcessed; 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (subStream.Pos == volSize) 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamIndex++; 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _offsetPos = 0; 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (realProcessed == 0 && curSize != 0) 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 184baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (seekOrigin >= 3) 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return STG_E_INVALIDFUNCTION; 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch(seekOrigin) 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case STREAM_SEEK_SET: 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _absPos = offset; 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case STREAM_SEEK_CUR: 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _absPos += offset; 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case STREAM_SEEK_END: 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _absPos = _length + offset; 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _offsetPos = _absPos; 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (newPosition != NULL) 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *newPosition = _absPos; 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamIndex = 0; 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 207baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP COutMultiVolStream::SetSize(UInt64 newSize) 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (newSize < 0) 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i = 0; 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (i < Streams.Size()) 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSubStreamInfo &subStream = Streams[i++]; 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((UInt64)newSize < subStream.RealSize) 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(subStream.Stream->SetSize(newSize)); 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.RealSize = newSize; 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newSize -= subStream.RealSize; 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (i < Streams.Size()) 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSubStreamInfo &subStream = Streams.Back(); 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStream.Stream.Release(); 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NDirectory::DeleteFileAlways(subStream.Name); 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Streams.DeleteBack(); 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _offsetPos = _absPos; 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streamIndex = 0; 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _length = newSize; 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 238baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kDefaultArchiveType = L"7z"; 239baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kSFXExtension = 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _WIN32 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync L"exe"; 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync L""; 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 246baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CUpdateOptions::Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath) 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (formatIndices.Size() > 1) 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int arcTypeIndex = -1; 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (formatIndices.Size() != 0) 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcTypeIndex = formatIndices[0]; 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (arcTypeIndex >= 0) 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MethodMode.FormatIndex = arcTypeIndex; 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath); 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // It works incorrectly for update command if archive has some non-default extension! 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (MethodMode.FormatIndex < 0) 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType); 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (MethodMode.FormatIndex < 0) 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex]; 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!arcInfo.UpdateEnabled) 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString typeExt = arcInfo.GetMainExt(); 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString ext = typeExt; 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (SfxMode) 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ext = kSFXExtension; 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ArchivePath.BaseExtension = ext; 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ArchivePath.VolExtension = typeExt; 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ArchivePath.ParseFromPath(arcPath); 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < Commands.Size(); i++) 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateArchiveCommand &uc = Commands[i]; 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uc.ArchivePath.BaseExtension = ext; 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uc.ArchivePath.VolExtension = typeExt; 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync uc.ArchivePath.ParseFromPath(uc.UserArchivePath); 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* 285baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CUpdateProduceCallbackImp: public IUpdateProduceCallback 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CObjectVector<CArcItem> *_arcItems; 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IUpdateCallbackUI *_callback; 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateProduceCallbackImp(const CObjectVector<CArcItem> *a, 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IUpdateCallbackUI *callback): _arcItems(a), _callback(callback) {} 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync virtual HRESULT ShowDeleteFile(int arcIndex); 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 295baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CUpdateProduceCallbackImp::ShowDeleteFile(int arcIndex) 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _callback->ShowDeleteFile((*_arcItems)[arcIndex].Name); 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/ 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 301baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT Compress( 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCodecs *codecs, 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CActionSet &actionSet, 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IInArchive *archive, 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CCompressionMethodMode &compressionMethod, 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchivePath &archivePath, 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CObjectVector<CArcItem> &arcItems, 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool shareForWrite, 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool stdInMode, 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* const UString & stdInFileName, */ 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool stdOutMode, 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CDirItems &dirItems, 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool sfxMode, 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &sfxModule, 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CRecordVector<UInt64> &volumesSizes, 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTempFiles &tempFiles, 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateErrorInfo &errorInfo, 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IUpdateCallbackUI *callback) 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IOutArchive> outArchive; 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (archive != NULL) 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IInArchive> archive2 = archive; 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result != S_OK) 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw kUpdateIsNotSupoorted; 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive)); 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef EXTERNAL_CODECS 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (setCompressCodecsInfo) 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (outArchive == 0) 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw kUpdateIsNotSupoorted; 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NFileTimeType::EEnum fileTimeType; 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 value; 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(outArchive->GetFileTimeType(&value)); 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch(value) 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NFileTimeType::kWindows: 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NFileTimeType::kUnix: 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NFileTimeType::kDOS: 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fileTimeType = (NFileTimeType::EEnum)value; 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<CUpdatePair2> updatePairs2; 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<CUpdatePair> updatePairs; 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs); // must be done only once!!! 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // CUpdateProduceCallbackImp upCallback(&arcItems, callback); 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UpdateProduce(updatePairs, actionSet, updatePairs2, NULL /* &upCallback */); 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numFiles = 0; 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < updatePairs2.Size(); i++) 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (updatePairs2[i].NewData) 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numFiles++; 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->SetNumFiles(numFiles)); 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->ShareForWrite = shareForWrite; 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->StdInMode = stdInMode; 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->Callback = callback; 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->DirItems = &dirItems; 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->ArcItems = &arcItems; 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->UpdatePairs = &updatePairs2; 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialOutStream> outStream; 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!stdOutMode) 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString resultPath; 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int pos; 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NFile::NDirectory::MyGetFullPathName(archivePath.GetFinalPath(), resultPath, pos)) 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw 1417161; 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); 397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COutFileStream *outStreamSpec = NULL; 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COutMultiVolStream *volStreamSpec = NULL; 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (volumesSizes.Size() == 0) 403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (stdOutMode) 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStream = new CStdOutFileStream; 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStreamSpec = new COutFileStream; 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStream = outStreamSpec; 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool isOK = false; 411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString realPath; 412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < (1 << 16); i++) 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (archivePath.Temp) 415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i > 0) 417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t s[16]; 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ConvertUInt32ToString(i, s); 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync archivePath.TempPostfix = s; 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync realPath = archivePath.GetTempPath(); 423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync realPath = archivePath.GetFinalPath(); 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (outStreamSpec->Create(realPath, false)) 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempFiles.Paths.Add(realPath); 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync isOK = true; 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (::GetLastError() != ERROR_FILE_EXISTS) 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!archivePath.Temp) 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!isOK) 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = realPath; 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot open file"; 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (stdOutMode) 449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volStreamSpec = new COutMultiVolStream; 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStream = volStreamSpec; 452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volStreamSpec->Sizes = volumesSizes; 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L"."); 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volStreamSpec->TempFiles = &tempFiles; 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volStreamSpec->Init(); 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->VolumesSizes = volumesSizes; 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!archivePath.VolExtension.IsEmpty()) 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SetProperties(outArchive, compressionMethod.Properties)); 466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (sfxMode) 468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CInFileStream *sfxStreamSpec = new CInFileStream; 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IInStream> sfxStream(sfxStreamSpec); 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!sfxStreamSpec->Open(sfxModule)) 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot open SFX module"; 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = sfxModule; 476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialOutStream> sfxOutStream; 480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COutFileStream *outStreamSpec = NULL; 481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (volumesSizes.Size() == 0) 482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sfxOutStream = outStream; 483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStreamSpec = new COutFileStream; 486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sfxOutStream = outStreamSpec; 487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString realPath = archivePath.GetFinalPath(); 488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!outStreamSpec->Create(realPath, false)) 489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = realPath; 492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot open file"; 493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(NCompress::CopyStream(sfxStream, sfxOutStream, NULL)); 497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (outStreamSpec) 498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(outStreamSpec->Close()); 500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback); 504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync callback->Finilize(); 505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(result); 506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (outStreamSpec) 507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result = outStreamSpec->Close(); 508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (volStreamSpec) 509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync result = volStreamSpec->Close(); 510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 513baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, 514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CArc &arc, 515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CArcItem> &arcItems) 516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcItems.Clear(); 518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 numItems; 519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IInArchive *archive = arc.Archive; 520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(archive->GetNumberOfItems(&numItems)); 521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcItems.Reserve(numItems); 522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < numItems; i++) 523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArcItem ai; 525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(arc.GetItemPath(i, ai.Name)); 527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(IsArchiveItemFolder(archive, i, ai.IsDir)); 528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir); 529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined)); 530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPropVariant prop; 533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(archive->GetProperty(i, kpidSize, &prop)); 534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ai.SizeDefined = (prop.vt != VT_EMPTY); 535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ai.SizeDefined) 536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ai.Size = ConvertPropVariantToUInt64(prop); 537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CPropVariant prop; 541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(archive->GetProperty(i, kpidTimeType, &prop)); 542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_UI4) 543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ai.TimeType = (int)(NFileTimeType::EEnum)prop.ulVal; 545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch(ai.TimeType) 546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NFileTimeType::kWindows: 548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NFileTimeType::kUnix: 549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NFileTimeType::kDOS: 550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ai.IndexInServer = i; 558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcItems.Add(ai); 559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 564baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT UpdateWithItemLists( 565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCodecs *codecs, 566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateOptions &options, 567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IInArchive *archive, 568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CObjectVector<CArcItem> &arcItems, 569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CDirItems &dirItems, 570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTempFiles &tempFiles, 571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateErrorInfo &errorInfo, 572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IUpdateCallbackUI2 *callback) 573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for(int i = 0; i < options.Commands.Size(); i++) 575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateArchiveCommand &command = options.Commands[i]; 577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.StdOutMode) 578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->StartArchive(L"stdout", archive != 0)); 580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), 584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync i == 0 && options.UpdateArchiveItself && archive != 0)); 585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(Compress( 588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync codecs, 589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync command.ActionSet, archive, 590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.MethodMode, 591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync command.ArchivePath, 592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcItems, 593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.OpenShareForWrite, 594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.StdInMode, 595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* options.StdInFileName, */ 596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.StdOutMode, 597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dirItems, 598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.SfxMode, options.SfxModule, 599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.VolumesSizes, 600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempFiles, 601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo, callback)); 602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->FinishArchive()); 604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#if defined(_WIN32) && !defined(UNDER_CE) 609baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CCurrentDirRestorer 610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString _path; 612baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(_path); } 614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ~CCurrentDirRestorer() { RestoreDirectory();} 615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool RestoreDirectory() { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(_path)); } 616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 619baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CEnumDirItemUpdateCallback: public IEnumDirItemCallback 620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IUpdateCallbackUI2 *Callback; 622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT ScanProgress(UInt64 numFolders, UInt64 numFiles, const wchar_t *path) 623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return Callback->ScanProgress(numFolders, numFiles, path); 625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _WIN32 629baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef ULONG (FAR PASCAL MY_MAPISENDDOCUMENTS)( 630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ULONG_PTR ulUIParam, 631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LPSTR lpszDelimChar, 632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LPSTR lpszFilePaths, 633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync LPSTR lpszFileNames, 634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ULONG ulReserved 635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync); 636baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef MY_MAPISENDDOCUMENTS FAR *MY_LPMAPISENDDOCUMENTS; 637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 639baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT UpdateArchive( 640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCodecs *codecs, 641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const NWildcard::CCensor &censor, 642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateOptions &options, 643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateErrorInfo &errorInfo, 644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IOpenCallbackUI *openCallback, 645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IUpdateCallbackUI2 *callback) 646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.StdOutMode && options.EMailMode) 648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode)) 651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.SfxMode) 654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CProperty property; 656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync property.Name = L"rsfx"; 657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync property.Value = L"on"; 658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.MethodMode.Properties.Add(property); 659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.SfxModule.IsEmpty()) 660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"SFX file is not specified"; 662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString name = options.SfxModule; 665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef UNDER_CE 666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NFind::DoesFileExist(name)) 667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule)) 669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot find specified SFX module"; 673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = name; 674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveLink arcLink; 680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString arcPath = options.ArchivePath.GetFinalPath(); 681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.ArchivePath.OriginalPath.IsEmpty()) 683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NFind::CFileInfoW fi; 685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fi.Find(arcPath)) 686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fi.IsDir()) 688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw "there is no such archive"; 689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.VolumesSizes.Size() > 0) 690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CIntVector formatIndices; 692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.MethodMode.FormatIndex >= 0) 693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync formatIndices.Add(options.MethodMode.FormatIndex); 694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = arcLink.Open2(codecs, formatIndices, false, NULL, arcPath, openCallback); 695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result == E_ABORT) 696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->OpenResult(arcPath, result)); 698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(result); 699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (arcLink.VolumePaths.Size() > 1) 700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = (DWORD)E_NOTIMPL; 702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"Updating for multivolume archives is not implemented"; 703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_NOTIMPL; 704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArc &arc = arcLink.Arcs.Back(); 707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arc.MTimeDefined = !fi.IsDevice; 708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arc.MTime = fi.MTime; 709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (archiveType.IsEmpty()) 715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw "type of archive is not specified"; 716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CDirItems dirItems; 720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.StdInMode) 721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CDirItem di; 723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync di.Name = options.StdInFileName; 724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync di.Size = (UInt64)(Int64)-1; 725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync di.Attrib = 0; 726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NTime::GetCurUtcFileTime(di.MTime); 727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync di.CTime = di.ATime = di.MTime; 728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dirItems.Items.Add(di); 729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool needScanning = false; 733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for(int i = 0; i < options.Commands.Size(); i++) 734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.Commands[i].ActionSet.NeedScanning()) 735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync needScanning = true; 736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (needScanning) 737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CEnumDirItemUpdateCallback enumCallback; 739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync enumCallback.Callback = callback; 740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->StartScanning()); 741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UStringVector errorPaths; 742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<DWORD> errorCodes; 743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes); 744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < errorPaths.Size(); i++) 745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i])); 747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res != S_OK) 749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (res != E_ABORT) 751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"Scanning error"; 752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(callback->FinishScanning()); 755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString tempDirPrefix; 759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool usesTempDir = false; 760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _WIN32 762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NDirectory::CTempDirectoryW tempDirectory; 763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.EMailMode && options.EMailRemoveAfter) 764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempDirectory.Create(kTempFolderPrefix); 766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempDirPrefix = tempDirectory.GetPath(); 767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NormalizeDirPathPrefix(tempDirPrefix); 768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync usesTempDir = true; 769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CTempFiles tempFiles; 773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool createTempFile = false; 775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool thereIsInArchive = arcLink.IsOpen; 777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.StdOutMode && options.UpdateArchiveItself) 779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchivePath &ap = options.Commands[0].ArchivePath; 781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ap = options.ArchivePath; 782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) 783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((thereIsInArchive || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) 784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync createTempFile = true; 786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ap.Temp = true; 787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.WorkingDir.IsEmpty()) 788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ap.TempPrefix = options.WorkingDir; 790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NormalizeDirPathPrefix(ap.TempPrefix); 791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for(int i = 0; i < options.Commands.Size(); i++) 796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchivePath &ap = options.Commands[i].ArchivePath; 798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (usesTempDir) 799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // Check it 801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ap.Prefix = tempDirPrefix; 802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // ap.Temp = true; 803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // ap.TempPrefix = tempDirPrefix; 804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!options.StdOutMode && 806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync (i > 0 || !createTempFile)) 807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &path = ap.GetFinalPath(); 809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (NFind::DoesFileOrDirExist(path)) 810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = 0; 812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"The file already exists"; 813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = path; 814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CArcItem> arcItems; 820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (thereIsInArchive) 821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(EnumerateInArchiveItems(censor, arcLink.Arcs.Back(), arcItems)); 823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(UpdateWithItemLists(codecs, options, 826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync thereIsInArchive ? arcLink.GetArchive() : 0, 827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcItems, dirItems, 828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempFiles, errorInfo, callback)); 829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (thereIsInArchive) 831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(arcLink.Close()); 833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync arcLink.Release(); 834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync tempFiles.Paths.Clear(); 837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (createTempFile) 838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync try 840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchivePath &ap = options.Commands[0].ArchivePath; 842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UString &tempPath = ap.GetTempPath(); 843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (thereIsInArchive) 844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NDirectory::DeleteFileAlways(arcPath)) 845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot delete the file"; 848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = arcPath; 849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NDirectory::MyMoveFile(tempPath, arcPath)) 852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot move the file"; 855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName = tempPath; 856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.FileName2 = arcPath; 857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(...) 861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 862baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw; 863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #if defined(_WIN32) && !defined(UNDER_CE) 867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (options.EMailMode) 868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NDLL::CLibrary mapiLib; 870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!mapiLib.Load(TEXT("Mapi32.dll"))) 871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot load Mapi32.dll"; 874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_LPMAPISENDDOCUMENTS fnSend = (MY_LPMAPISENDDOCUMENTS)mapiLib.GetProc("MAPISendDocuments"); 877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (fnSend == 0) 878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 880baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"7-Zip cannot find MAPISendDocuments function"; 881baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 882baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 883baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UStringVector fullPaths; 884baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 885baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for(i = 0; i < options.Commands.Size(); i++) 886baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 887baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchivePath &ap = options.Commands[i].ArchivePath; 888baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString arcPath; 889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath)) 890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 891baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.SystemError = ::GetLastError(); 892baa3858d3f5d128a5c8466b700098109edcad5f2repo sync errorInfo.Message = L"GetFullPathName error"; 893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 894baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 895baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fullPaths.Add(arcPath); 896baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 897baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCurrentDirRestorer curDirRestorer; 898baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for(i = 0; i < fullPaths.Size(); i++) 899baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 900baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString arcPath = fullPaths[i]; 901baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString fileName = ExtractFileNameFromPath(arcPath); 902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync AString path = GetAnsiString(arcPath); 903baa3858d3f5d128a5c8466b700098109edcad5f2repo sync AString name = GetAnsiString(fileName); 904baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // Warning!!! MAPISendDocuments function changes Current directory 905baa3858d3f5d128a5c8466b700098109edcad5f2repo sync fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); 906baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 911