diff -r 5f819b90d479 -r 99b265e0d1d0 misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp --- a/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp Thu Oct 11 23:43:31 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,464 +0,0 @@ -// 7zHandlerOut.cpp - -#include "StdAfx.h" - -#include "7zHandler.h" -#include "7zOut.h" -#include "7zUpdate.h" - -#include "../../../Windows/PropVariant.h" - -#include "../../../Common/ComTry.h" -#include "../../../Common/StringToInt.h" -#include "../../IPassword.h" -#include "../../ICoder.h" - -#include "../Common/ItemNameUtils.h" -#include "../Common/ParseProperties.h" - -using namespace NWindows; - -namespace NArchive { -namespace N7z { - -static const wchar_t *kLZMAMethodName = L"LZMA"; -static const wchar_t *kCopyMethod = L"Copy"; -static const wchar_t *kDefaultMethodName = kLZMAMethodName; - -static const UInt32 kLzmaAlgorithmX5 = 1; -static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; -static const UInt32 kDictionaryForHeaders = 1 << 20; -static const UInt32 kNumFastBytesForHeaders = 273; -static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5; - -static inline bool IsCopyMethod(const UString &methodName) - { return (methodName.CompareNoCase(kCopyMethod) == 0); } - -STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) -{ - *type = NFileTimeType::kWindows; - return S_OK; -} - -HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode, - IArchiveUpdateCallback *updateCallback) -{ - CMyComPtr getTextPassword; - if (!getTextPassword) - { - CMyComPtr udateCallback2(updateCallback); - udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword); - } - - if (getTextPassword) - { - CMyComBSTR password; - Int32 passwordIsDefined; - RINOK(getTextPassword->CryptoGetTextPassword2( - &passwordIsDefined, &password)); - methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); - if (methodMode.PasswordIsDefined) - methodMode.Password = password; - } - else - methodMode.PasswordIsDefined = false; - return S_OK; -} - -HRESULT CHandler::SetCompressionMethod( - CCompressionMethodMode &methodMode, - CCompressionMethodMode &headerMethod) -{ - HRESULT res = SetCompressionMethod(methodMode, _methods - #ifdef COMPRESS_MT - , _numThreads - #endif - ); - RINOK(res); - methodMode.Binds = _binds; - - if (_compressHeaders) - { - // headerMethod.Methods.Add(methodMode.Methods.Back()); - - CObjectVector headerMethodInfoVector; - COneMethodInfo oneMethodInfo; - oneMethodInfo.MethodName = kLZMAMethodName; - { - CProp property; - property.Id = NCoderPropID::kMatchFinder; - property.Value = kLzmaMatchFinderForHeaders; - oneMethodInfo.Properties.Add(property); - } - { - CProp property; - property.Id = NCoderPropID::kAlgorithm; - property.Value = kAlgorithmForHeaders; - oneMethodInfo.Properties.Add(property); - } - { - CProp property; - property.Id = NCoderPropID::kNumFastBytes; - property.Value = UInt32(kNumFastBytesForHeaders); - oneMethodInfo.Properties.Add(property); - } - { - CProp property; - property.Id = NCoderPropID::kDictionarySize; - property.Value = UInt32(kDictionaryForHeaders); - oneMethodInfo.Properties.Add(property); - } - headerMethodInfoVector.Add(oneMethodInfo); - HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector - #ifdef COMPRESS_MT - ,1 - #endif - ); - RINOK(res); - } - return S_OK; -} - -HRESULT CHandler::SetCompressionMethod( - CCompressionMethodMode &methodMode, - CObjectVector &methodsInfo - #ifdef COMPRESS_MT - , UInt32 numThreads - #endif - ) -{ - UInt32 level = _level; - - if (methodsInfo.IsEmpty()) - { - COneMethodInfo oneMethodInfo; - oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName); - methodsInfo.Add(oneMethodInfo); - } - - bool needSolid = false; - for(int i = 0; i < methodsInfo.Size(); i++) - { - COneMethodInfo &oneMethodInfo = methodsInfo[i]; - SetCompressionMethod2(oneMethodInfo - #ifdef COMPRESS_MT - , numThreads - #endif - ); - - if (!IsCopyMethod(oneMethodInfo.MethodName)) - needSolid = true; - - CMethodFull methodFull; - - if (!FindMethod( - EXTERNAL_CODECS_VARS - oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams)) - return E_INVALIDARG; - methodFull.Properties = oneMethodInfo.Properties; - methodMode.Methods.Add(methodFull); - - if (!_numSolidBytesDefined) - { - for (int j = 0; j < methodFull.Properties.Size(); j++) - { - const CProp &prop = methodFull.Properties[j]; - if ((prop.Id == NCoderPropID::kDictionarySize || - prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) - { - _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; - const UInt64 kMinSize = (1 << 24); - if (_numSolidBytes < kMinSize) - _numSolidBytes = kMinSize; - _numSolidBytesDefined = true; - break; - } - } - } - } - - if (!needSolid && !_numSolidBytesDefined) - { - _numSolidBytesDefined = true; - _numSolidBytes = 0; - } - return S_OK; -} - -static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined) -{ - filetimeIsDefined = false; - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(index, propID, &propVariant)); - if (propVariant.vt == VT_FILETIME) - { - filetime = propVariant.filetime; - filetimeIsDefined = true; - } - else if (propVariant.vt != VT_EMPTY) - return E_INVALIDARG; - return S_OK; -} - -STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *updateCallback) -{ - COM_TRY_BEGIN - - const CArchiveDatabaseEx *database = 0; - #ifdef _7Z_VOL - if(_volumes.Size() > 1) - return E_FAIL; - const CVolume *volume = 0; - if (_volumes.Size() == 1) - { - volume = &_volumes.Front(); - database = &volume->Database; - } - #else - if (_inStream != 0) - database = &_database; - #endif - - // CRecordVector compressStatuses; - CObjectVector updateItems; - // CRecordVector copyIndices; - - // CMyComPtr updateCallback2; - // updateCallback->QueryInterface(&updateCallback2); - - for(UInt32 i = 0; i < numItems; i++) - { - Int32 newData; - Int32 newProperties; - UInt32 indexInArchive; - if (!updateCallback) - return E_FAIL; - RINOK(updateCallback->GetUpdateItemInfo(i, - &newData, &newProperties, &indexInArchive)); - CUpdateItem updateItem; - updateItem.NewProperties = IntToBool(newProperties); - updateItem.NewData = IntToBool(newData); - updateItem.IndexInArchive = indexInArchive; - updateItem.IndexInClient = i; - updateItem.IsAnti = false; - updateItem.Size = 0; - - if (updateItem.IndexInArchive != -1) - { - const CFileItem &fileItem = database->Files[updateItem.IndexInArchive]; - updateItem.Name = fileItem.Name; - updateItem.IsDirectory = fileItem.IsDirectory; - updateItem.Size = fileItem.UnPackSize; - updateItem.IsAnti = fileItem.IsAnti; - - updateItem.CreationTime = fileItem.CreationTime; - updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined; - updateItem.LastWriteTime = fileItem.LastWriteTime; - updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined; - updateItem.LastAccessTime = fileItem.LastAccessTime; - updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined; - } - - if (updateItem.NewProperties) - { - bool nameIsDefined; - bool folderStatusIsDefined; - { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); - if (propVariant.vt == VT_EMPTY) - updateItem.AttributesAreDefined = false; - else if (propVariant.vt != VT_UI4) - return E_INVALIDARG; - else - { - updateItem.Attributes = propVariant.ulVal; - updateItem.AttributesAreDefined = true; - } - } - - RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined)); - RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined)); - RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined)); - - { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); - if (propVariant.vt == VT_EMPTY) - nameIsDefined = false; - else if (propVariant.vt != VT_BSTR) - return E_INVALIDARG; - else - { - updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal); - nameIsDefined = true; - } - } - { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); - if (propVariant.vt == VT_EMPTY) - folderStatusIsDefined = false; - else if (propVariant.vt != VT_BOOL) - return E_INVALIDARG; - else - { - updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); - folderStatusIsDefined = true; - } - } - - { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant)); - if (propVariant.vt == VT_EMPTY) - updateItem.IsAnti = false; - else if (propVariant.vt != VT_BOOL) - return E_INVALIDARG; - else - updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE); - } - - if (updateItem.IsAnti) - { - updateItem.AttributesAreDefined = false; - - updateItem.IsCreationTimeDefined = false; - updateItem.IsLastWriteTimeDefined = false; - updateItem.IsLastAccessTimeDefined = false; - - updateItem.Size = 0; - } - - if (!folderStatusIsDefined && updateItem.AttributesAreDefined) - updateItem.SetDirectoryStatusFromAttributes(); - } - - if (updateItem.NewData) - { - NCOM::CPropVariant propVariant; - RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); - if (propVariant.vt != VT_UI8) - return E_INVALIDARG; - updateItem.Size = (UInt64)propVariant.uhVal.QuadPart; - if (updateItem.Size != 0 && updateItem.IsAnti) - return E_INVALIDARG; - } - updateItems.Add(updateItem); - } - - CCompressionMethodMode methodMode, headerMethod; - RINOK(SetCompressionMethod(methodMode, headerMethod)); - #ifdef COMPRESS_MT - methodMode.NumThreads = _numThreads; - headerMethod.NumThreads = 1; - #endif - - RINOK(SetPassword(methodMode, updateCallback)); - - bool compressMainHeader = _compressHeaders; // check it - - if (methodMode.PasswordIsDefined) - { - compressMainHeader = true; - if(_encryptHeaders) - RINOK(SetPassword(headerMethod, updateCallback)); - } - - if (numItems < 2) - compressMainHeader = false; - - CUpdateOptions options; - options.Method = &methodMode; - options.HeaderMethod = (_compressHeaders || - (methodMode.PasswordIsDefined && _encryptHeaders)) ? - &headerMethod : 0; - options.UseFilters = _level != 0 && _autoFilter; - options.MaxFilter = _level >= 8; - - options.HeaderOptions.CompressMainHeader = compressMainHeader; - options.HeaderOptions.WriteModified = WriteModified; - options.HeaderOptions.WriteCreated = WriteCreated; - options.HeaderOptions.WriteAccessed = WriteAccessed; - - options.NumSolidFiles = _numSolidFiles; - options.NumSolidBytes = _numSolidBytes; - options.SolidExtension = _solidExtension; - options.RemoveSfxBlock = _removeSfxBlock; - options.VolumeMode = _volumeMode; - return Update( - EXTERNAL_CODECS_VARS - #ifdef _7Z_VOL - volume ? volume->Stream: 0, - volume ? database: 0, - #else - _inStream, - database, - #endif - updateItems, outStream, updateCallback, options); - COM_TRY_END -} - -static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream) -{ - stream = 0; - int index = ParseStringToUInt32(srcString, coder); - if (index == 0) - return E_INVALIDARG; - srcString.Delete(0, index); - if (srcString[0] == 'S') - { - srcString.Delete(0); - int index = ParseStringToUInt32(srcString, stream); - if (index == 0) - return E_INVALIDARG; - srcString.Delete(0, index); - } - return S_OK; -} - -static HRESULT GetBindInfo(UString &srcString, CBind &bind) -{ - RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream)); - if (srcString[0] != ':') - return E_INVALIDARG; - srcString.Delete(0); - RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream)); - if (!srcString.IsEmpty()) - return E_INVALIDARG; - return S_OK; -} - -STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) -{ - COM_TRY_BEGIN - _binds.Clear(); - BeforeSetProperty(); - - for (int i = 0; i < numProperties; i++) - { - UString name = names[i]; - name.MakeUpper(); - if (name.IsEmpty()) - return E_INVALIDARG; - - const PROPVARIANT &value = values[i]; - - if (name[0] == 'B') - { - name.Delete(0); - CBind bind; - RINOK(GetBindInfo(name, bind)); - _binds.Add(bind); - continue; - } - - RINOK(SetProperty(name, value)); - } - - return S_OK; - COM_TRY_END -} - -}}