1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zHandlerOut.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Windows/PropVariant.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/ComTry.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/StringToInt.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../ICoder.h" 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ItemNameUtils.h" 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ParseProperties.h" 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zHandler.h" 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zOut.h" 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zUpdate.h" 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows; 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 21baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive { 22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z { 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 24baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kLZMAMethodName = L"LZMA"; 25baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kCopyMethod = L"Copy"; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kDefaultMethodName = kLZMAMethodName; 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kLzmaAlgorithmX5 = 1; 29baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const wchar_t *kLzmaMatchFinderForHeaders = L"BT2"; 30baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kDictionaryForHeaders = 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef UNDER_CE 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1 << 18 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1 << 20 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kNumFastBytesForHeaders = 273; 38baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 40baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline bool IsCopyMethod(const UString &methodName) 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { return (methodName.CompareNoCase(kCopyMethod) == 0); } 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *type = NFileTimeType::kWindows; 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 49baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CHandler::SetCompressionMethod( 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCompressionMethodMode &methodMode, 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCompressionMethodMode &headerMethod) 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res = SetCompressionMethod(methodMode, _methods 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _7ZIP_ST 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync , _numThreads 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(res); 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodMode.Binds = _binds; 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_compressHeaders) 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // headerMethod.Methods.Add(methodMode.Methods.Back()); 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<COneMethodInfo> headerMethodInfoVector; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COneMethodInfo oneMethodInfo; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.MethodName = kLZMAMethodName; 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CProp prop; 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Id = NCoderPropID::kMatchFinder; 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Value = kLzmaMatchFinderForHeaders; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.Props.Add(prop); 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CProp prop; 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Id = NCoderPropID::kAlgorithm; 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Value = kAlgorithmForHeaders; 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.Props.Add(prop); 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CProp prop; 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Id = NCoderPropID::kNumFastBytes; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Value = (UInt32)kNumFastBytesForHeaders; 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.Props.Add(prop); 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CProp prop; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Id = NCoderPropID::kDictionarySize; 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Value = (UInt32)kDictionaryForHeaders; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.Props.Add(prop); 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerMethodInfoVector.Add(oneMethodInfo); 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _7ZIP_ST 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync , 1 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(res); 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 103baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CHandler::SetCompressionMethod( 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCompressionMethodMode &methodMode, 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<COneMethodInfo> &methodsInfo 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _7ZIP_ST 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync , UInt32 numThreads 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ) 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 level = _level; 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (methodsInfo.IsEmpty()) 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COneMethodInfo oneMethodInfo; 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName); 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodsInfo.Add(oneMethodInfo); 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool needSolid = false; 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for(int i = 0; i < methodsInfo.Size(); i++) 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COneMethodInfo &oneMethodInfo = methodsInfo[i]; 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SetCompressionMethod2(oneMethodInfo 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _7ZIP_ST 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync , numThreads 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!IsCopyMethod(oneMethodInfo.MethodName)) 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync needSolid = true; 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMethodFull methodFull; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!FindMethod( 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_VARS 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams)) 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodFull.Props = oneMethodInfo.Props; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodMode.Methods.Add(methodFull); 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!_numSolidBytesDefined) 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int j = 0; j < methodFull.Props.Size(); j++) 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CProp &prop = methodFull.Props[j]; 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((prop.Id == NCoderPropID::kDictionarySize || 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4) 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7; 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 kMinSize = (1 << 24); 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_numSolidBytes < kMinSize) 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numSolidBytes = kMinSize; 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numSolidBytesDefined = true; 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!needSolid && !_numSolidBytesDefined) 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numSolidBytesDefined = true; 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _numSolidBytes = 0; 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 169baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined) 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft = 0; 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ftDefined = false; 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!writeTime) 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetProperty(index, propID, &prop)); 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_FILETIME) 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32); 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ftDefined = true; 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (prop.vt != VT_EMPTY) 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 187baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IArchiveUpdateCallback *updateCallback) 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_BEGIN 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CArchiveDatabaseEx *db = 0; 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _7Z_VOL 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_volumes.Size() > 1) 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CVolume *volume = 0; 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_volumes.Size() == 1) 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volume = &_volumes.Front(); 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db = &volume->Database; 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_inStream != 0) 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db = &_db; 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CUpdateItem> updateItems; 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt32 i = 0; i < numItems; i++) 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 newData, newProps; 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 indexInArchive; 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!updateCallback) 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_FAIL; 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateItem ui; 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.NewProps = IntToBool(newProps); 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.NewData = IntToBool(newData); 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IndexInArchive = indexInArchive; 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IndexInClient = i; 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IsAnti = false; 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Size = 0; 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ui.IndexInArchive != -1) 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (db == 0 || ui.IndexInArchive >= db->Files.Size()) 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CFileItem &fi = db->Files[ui.IndexInArchive]; 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Name = fi.Name; 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IsDir = fi.IsDir; 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Size = fi.Size; 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IsAnti = db->IsItemAnti(ui.IndexInArchive); 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime); 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime); 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime); 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ui.NewProps) 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool nameIsDefined; 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool folderStatusIsDefined; 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop)); 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_EMPTY) 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.AttribDefined = false; 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (prop.vt != VT_UI4) 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Attrib = prop.ulVal; 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.AttribDefined = true; 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // we need MTime to sort files. 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined)); 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined)); 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined)); 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetProperty(i, kpidPath, &prop)); 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_EMPTY) 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nameIsDefined = false; 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (prop.vt != VT_BSTR) 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Name = NItemName::MakeLegalName(prop.bstrVal); 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nameIsDefined = true; 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop)); 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_EMPTY) 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderStatusIsDefined = false; 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (prop.vt != VT_BOOL) 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IsDir = (prop.boolVal != VARIANT_FALSE); 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderStatusIsDefined = true; 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop)); 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt == VT_EMPTY) 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IsAnti = false; 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (prop.vt != VT_BOOL) 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.IsAnti = (prop.boolVal != VARIANT_FALSE); 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ui.IsAnti) 301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.AttribDefined = false; 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.CTimeDefined = false; 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.ATimeDefined = false; 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.MTimeDefined = false; 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Size = 0; 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!folderStatusIsDefined && ui.AttribDefined) 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.SetDirStatusFromAttrib(); 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ui.NewData) 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(updateCallback->GetProperty(i, kpidSize, &prop)); 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_UI8) 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ui.Size = (UInt64)prop.uhVal.QuadPart; 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ui.Size != 0 && ui.IsAnti) 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateItems.Add(ui); 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CCompressionMethodMode methodMode, headerMethod; 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SetCompressionMethod(methodMode, headerMethod)); 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _7ZIP_ST 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodMode.NumThreads = _numThreads; 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerMethod.NumThreads = 1; 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICryptoGetTextPassword2> getPassword2; 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2); 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (getPassword2) 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComBSTR password; 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 passwordIsDefined; 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password)); 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodMode.PasswordIsDefined = IntToBool(passwordIsDefined); 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (methodMode.PasswordIsDefined) 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodMode.Password = password; 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync methodMode.PasswordIsDefined = false; 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool compressMainHeader = _compressHeaders; // check it 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool encryptHeaders = false; 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (methodMode.PasswordIsDefined) 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_encryptHeadersSpecified) 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encryptHeaders = _encryptHeaders; 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encryptHeaders = _passwordIsDefined; 361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync compressMainHeader = true; 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (encryptHeaders) 364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined; 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync headerMethod.Password = methodMode.Password; 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numItems < 2) 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync compressMainHeader = false; 372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CUpdateOptions options; 374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.Method = &methodMode; 375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0; 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.UseFilters = _level != 0 && _autoFilter; 377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.MaxFilter = _level >= 8; 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.HeaderOptions.CompressMainHeader = compressMainHeader; 380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.HeaderOptions.WriteCTime = WriteCTime; 381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.HeaderOptions.WriteATime = WriteATime; 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.HeaderOptions.WriteMTime = WriteMTime; 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.NumSolidFiles = _numSolidFiles; 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.NumSolidBytes = _numSolidBytes; 386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.SolidExtension = _solidExtension; 387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.RemoveSfxBlock = _removeSfxBlock; 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync options.VolumeMode = _volumeMode; 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COutArchive archive; 391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CArchiveDatabase newDatabase; 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICryptoGetTextPassword> getPassword; 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword); 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT res = Update( 397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_VARS 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _7Z_VOL 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volume ? volume->Stream: 0, 400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync volume ? db : 0, 401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _inStream, 403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db, 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateItems, 406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync archive, newDatabase, outStream, updateCallback, options 407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifndef _NO_CRYPTO 408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync , getPassword 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(res); 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync updateItems.ClearAndFree(); 415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return archive.WriteDatabase(EXTERNAL_CODECS_VARS 417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newDatabase, options.HeaderMethod, options.HeaderOptions); 418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_END 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 422baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream) 423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync stream = 0; 425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = ParseStringToUInt32(srcString, coder); 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index == 0) 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync srcString.Delete(0, index); 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (srcString[0] == 'S') 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync srcString.Delete(0); 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int index = ParseStringToUInt32(srcString, stream); 433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index == 0) 434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync srcString.Delete(0, index); 436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 440baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT GetBindInfo(UString &srcString, CBind &bind) 441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream)); 443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (srcString[0] != ':') 444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync srcString.Delete(0); 446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream)); 447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!srcString.IsEmpty()) 448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 452baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) 453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_BEGIN 455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _binds.Clear(); 456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BeforeSetProperty(); 457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < numProperties; i++) 459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString name = names[i]; 461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync name.MakeUpper(); 462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (name.IsEmpty()) 463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const PROPVARIANT &value = values[i]; 466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (name[0] == 'B') 468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync name.Delete(0); 470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBind bind; 471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(GetBindInfo(name, bind)); 472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _binds.Add(bind); 473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(SetProperty(name, value)); 477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_END 481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 484