1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// SplitHandler.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/ComTry.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/MyString.h" 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Windows/PropVariant.h" 9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/ProgressUtils.h" 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/RegisterArc.h" 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Compress/CopyCoder.h" 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Common/MultiStream.h" 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows; 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 19baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive { 20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NSplit { 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTATPROPSTG kProps[] = 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { NULL, kpidPath, VT_BSTR}, 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { NULL, kpidSize, VT_UI8} 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTATPROPSTG kArcProps[] = 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { NULL, kpidNumVolumes, VT_UI4} 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 33baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CHandler: 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public IInArchive, 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public IInArchiveGetStream, 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public CMyUnknownImp 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString _subName; 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CMyComPtr<IInStream> > _streams; 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> _sizes; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 _totalSize; 42baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream) 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync INTERFACE_IInArchive(;) 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 48baa3858d3f5d128a5c8466b700098109edcad5f2repo syncIMP_IInArchive_Props 49baa3858d3f5d128a5c8466b700098109edcad5f2repo syncIMP_IInArchive_ArcProps 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 51baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch(propID) 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case kpidMainSubfile: prop = (UInt32)0; break; 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case kpidNumVolumes: prop = (UInt32)_streams.Size(); break; 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Detach(value); 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 63baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstruct CSeqName 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString _unchangedPart; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString _changedPart; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool _splitStyle; 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString GetNextName() 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString newName; 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_splitStyle) 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numLetters = _changedPart.Length(); 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = numLetters - 1; i >= 0; i--) 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t c = _changedPart[i]; 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c == 'z') 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = 'a'; 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = c + newName; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (c == 'Z') 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = 'A'; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = c + newName; 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c++; 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((c == 'z' || c == 'Z') && i == 0) 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _unchangedPart += c; 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t newChar = (c == 'z') ? L'a' : L'A'; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName.Empty(); 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numLetters++; 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int k = 0; k < numLetters; k++) 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName += newChar; 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = c + newName; 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync i--; 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i >= 0; i--) 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = _changedPart[i] + newName; 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int i; 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numLetters = _changedPart.Length(); 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = numLetters - 1; i >= 0; i--) 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync wchar_t c = _changedPart[i]; 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (c == L'9') 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c = L'0'; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = c + newName; 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (i == 0) 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = UString(L'1') + newName; 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync c++; 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = c + newName; 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync i--; 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (; i >= 0; i--) 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync newName = _changedPart[i] + newName; 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _changedPart = newName; 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _unchangedPart + _changedPart; 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 137baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::Open(IInStream *stream, 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const UInt64 * /* maxCheckStartPosition */, 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IArchiveOpenCallback *openArchiveCallback) 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_BEGIN 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Close(); 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (openArchiveCallback == 0) 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // try 146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync &openVolumeCallback) != S_OK) 151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString name; 154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); 157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_BSTR) 158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync name = prop.bstrVal; 160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int dotPos = name.ReverseFind('.'); 163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString prefix, ext; 164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (dotPos >= 0) 165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prefix = name.Left(dotPos + 1); 167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ext = name.Mid(dotPos + 1); 168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ext = name; 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString extBig = ext; 172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync extBig.MakeUpper(); 173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSeqName seqName; 175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync int numLetters = 2; 177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool splitStyle = false; 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (extBig.Right(2) == L"AA") 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync splitStyle = true; 181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (numLetters < extBig.Length()) 182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (extBig[extBig.Length() - numLetters - 1] != 'A') 184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numLetters++; 186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else if (ext.Right(2) == L"01") 189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync while (numLetters < extBig.Length()) 191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (extBig[extBig.Length() - numLetters - 1] != '0') 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numLetters++; 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numLetters != ext.Length()) 197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streams.Add(stream); 203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync seqName._unchangedPart = prefix + ext.Left(extBig.Length() - numLetters); 205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync seqName._changedPart = ext.Right(numLetters); 206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync seqName._splitStyle = splitStyle; 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prefix.Length() < 1) 209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _subName = L"file"; 210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _subName = prefix.Left(prefix.Length() - 1); 212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _totalSize = 0; 214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size; 215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(openVolumeCallback->GetProperty(kpidSize, &prop)); 218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_UI8) 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size = prop.uhVal.QuadPart; 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _totalSize += size; 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _sizes.Add(size); 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (openArchiveCallback != NULL) 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 numFiles = _streams.Size(); 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UString fullName = seqName.GetNextName(); 234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<IInStream> nextStream; 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result == S_FALSE) 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result != S_OK) 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return result; 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!stream) 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCOM::CPropVariant prop; 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(openVolumeCallback->GetProperty(kpidSize, &prop)); 245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (prop.vt != VT_UI8) 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size = prop.uhVal.QuadPart; 248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _totalSize += size; 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _sizes.Add(size); 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streams.Add(nextStream); 252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (openArchiveCallback != NULL) 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 numFiles = _streams.Size(); 255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync catch(...) 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_END 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 269baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::Close() 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _sizes.Clear(); 272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _streams.Clear(); 273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 276baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) 277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *numItems = _streams.IsEmpty() ? 0 : 1; 279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 282baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) 283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NWindows::NCOM::CPropVariant prop; 285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync switch(propID) 286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case kpidPath: prop = _subName; break; 288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case kpidSize: 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case kpidPackSize: 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop = _totalSize; 291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync prop.Detach(value); 294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 297baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 testMode, IArchiveExtractCallback *extractCallback) 299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_BEGIN 301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numItems == 0) 302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numItems != (UInt32)-1 && (numItems != 1 || indices[0] != 0)) 304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 currentTotalSize = 0; 307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->SetTotal(_totalSize)); 308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialOutStream> outStream; 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Int32 askMode = testMode ? 310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NExtract::NAskMode::kTest : 311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NExtract::NAskMode::kExtract; 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->GetStream(0, &outStream, askMode)); 313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!testMode && !outStream) 314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(extractCallback->PrepareOperation(askMode)); 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; 318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; 319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CLocalProgress *lps = new CLocalProgress; 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ICompressProgressInfo> progress = lps; 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lps->Init(extractCallback, false); 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < _streams.Size(); i++) 325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync lps->InSize = lps->OutSize = currentTotalSize; 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(lps->SetCur()); 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync IInStream *inStream = _streams[i]; 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); 330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); 331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync currentTotalSize += copyCoderSpec->TotalSize; 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStream.Release(); 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return extractCallback->SetOperationResult(NExtract::NOperationResult::kOK); 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_END 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 338baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) 339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_BEGIN 341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (index != 0) 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return E_INVALIDARG; 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *stream = 0; 344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMultiStream *streamSpec = new CMultiStream; 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialInStream> streamTemp = streamSpec; 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (int i = 0; i < _streams.Size(); i++) 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMultiStream::CSubStreamInfo subStreamInfo; 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamInfo.Stream = _streams[i]; 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync subStreamInfo.Size = _sizes[i]; 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSpec->Streams.Add(subStreamInfo); 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSpec->Init(); 354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *stream = streamTemp.Detach(); 355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync COM_TRY_END 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 359baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic IInArchive *CreateArc() { return new CHandler; } 360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 361baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic CArcInfo g_ArcInfo = 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ L"Split", L"001", 0, 0xEA, { 0 }, 0, false, CreateArc, 0 }; 363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 364baa3858d3f5d128a5c8466b700098109edcad5f2repo syncREGISTER_ARC(Split) 365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 367