mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-06 05:15:00 -06:00
4.53 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
33ccab7e72
commit
051769bbc5
@@ -13,7 +13,9 @@
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/FilterCoder.h"
|
||||
|
||||
static UInt64 k_AES = 0x06F10701;
|
||||
static const UInt64 k_AES = 0x06F10701;
|
||||
static const UInt64 k_BCJ = 0x03030103;
|
||||
static const UInt64 k_BCJ2 = 0x0303011B;
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
@@ -59,7 +61,8 @@ HRESULT CEncoder::CreateMixerCoder(
|
||||
{
|
||||
const CMethodFull &methodFull = _options.Methods[i];
|
||||
_codersInfo.Add(CCoderInfo());
|
||||
// CCoderInfo &encodingInfo = _codersInfo.Back();
|
||||
CCoderInfo &encodingInfo = _codersInfo.Back();
|
||||
encodingInfo.MethodID = methodFull.Id;
|
||||
CMyComPtr<ICompressCoder> encoder;
|
||||
CMyComPtr<ICompressCoder2> encoder2;
|
||||
|
||||
@@ -176,7 +179,7 @@ HRESULT CEncoder::Encode(
|
||||
return E_FAIL;
|
||||
UInt32 mainCoderIndex, mainStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
|
||||
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
|
||||
|
||||
if (inStreamSize != NULL)
|
||||
{
|
||||
CRecordVector<const UInt64 *> sizePointers;
|
||||
@@ -235,6 +238,17 @@ HRESULT CEncoder::Encode(
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 progressIndex = mainCoderIndex;
|
||||
|
||||
for (i = 0; i < _codersInfo.Size(); i++)
|
||||
{
|
||||
const CCoderInfo &e = _codersInfo[i];
|
||||
if ((e.MethodID == k_BCJ || e.MethodID == k_BCJ2) && i + 1 < _codersInfo.Size())
|
||||
progressIndex = i + 1;
|
||||
}
|
||||
|
||||
_mixerCoderSpec->SetProgressCoderIndex(progressIndex);
|
||||
|
||||
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
|
||||
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
|
||||
|
||||
|
||||
@@ -149,16 +149,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
);
|
||||
// CDecoder1 decoder;
|
||||
|
||||
UInt64 currentImportantTotalUnPacked = 0;
|
||||
UInt64 currentTotalPacked = 0;
|
||||
UInt64 currentTotalUnPacked = 0;
|
||||
UInt64 totalFolderUnPacked;
|
||||
UInt64 totalFolderPacked;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
||||
currentImportantTotalUnPacked += totalFolderUnPacked)
|
||||
currentTotalUnPacked += totalFolderUnPacked,
|
||||
currentTotalPacked += totalFolderPacked)
|
||||
{
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
lps->InSize = currentTotalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||
totalFolderUnPacked = efi.UnPackSize;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked));
|
||||
totalFolderPacked = 0;
|
||||
|
||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||
@@ -194,14 +205,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
CNum folderIndex = efi.FolderIndex;
|
||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress, NULL, ¤tImportantTotalUnPacked);
|
||||
totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
|
||||
|
||||
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
|
||||
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
|
||||
@@ -225,7 +229,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
&database.PackSizes[packStreamIndex],
|
||||
folderInfo,
|
||||
outStream,
|
||||
compressProgress
|
||||
progress
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword
|
||||
#endif
|
||||
|
||||
@@ -53,14 +53,10 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _SFX
|
||||
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
@@ -72,27 +68,64 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidSolid, VT_BOOL},
|
||||
{ NULL, kpidNumBlocks, VT_UI4}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidMethod:
|
||||
{
|
||||
UString resString;
|
||||
CRecordVector<UInt64> ids;
|
||||
int i;
|
||||
for (i = 0; i < _database.Folders.Size(); i++)
|
||||
{
|
||||
const CFolder &f = _database.Folders[i];
|
||||
for (int j = f.Coders.Size() - 1; j >= 0; j--)
|
||||
ids.AddToUniqueSorted(f.Coders[j].MethodID);
|
||||
}
|
||||
|
||||
for (i = 0; i < ids.Size(); i++)
|
||||
{
|
||||
UInt64 id = ids[i];
|
||||
UString methodName;
|
||||
/* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
|
||||
if (methodName.IsEmpty())
|
||||
methodName = ConvertMethodIdToString(id);
|
||||
if (!resString.IsEmpty())
|
||||
resString += L' ';
|
||||
resString += methodName;
|
||||
}
|
||||
prop = resString;
|
||||
break;
|
||||
}
|
||||
case kpidSolid: prop = _database.IsSolid(); break;
|
||||
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime,
|
||||
NWindows::NCOM::CPropVariant &propVariant)
|
||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
if (timeDefined)
|
||||
propVariant = unixTime;
|
||||
prop = unixTime;
|
||||
}
|
||||
|
||||
#ifndef _SFX
|
||||
@@ -171,7 +204,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
|
||||
/*
|
||||
const CRef2 &ref2 = _refs[index];
|
||||
@@ -196,68 +229,68 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
case kpidPath:
|
||||
{
|
||||
if (!item.Name.IsEmpty())
|
||||
propVariant = NItemName::GetOSName(item.Name);
|
||||
prop = NItemName::GetOSName(item.Name);
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory;
|
||||
prop = item.IsDirectory;
|
||||
break;
|
||||
case kpidSize:
|
||||
{
|
||||
propVariant = item.UnPackSize;
|
||||
// propVariant = ref2.UnPackSize;
|
||||
prop = item.UnPackSize;
|
||||
// prop = ref2.UnPackSize;
|
||||
break;
|
||||
}
|
||||
case kpidPosition:
|
||||
{
|
||||
/*
|
||||
if (ref2.Refs.Size() > 1)
|
||||
propVariant = ref2.StartPos;
|
||||
prop = ref2.StartPos;
|
||||
else
|
||||
*/
|
||||
if (item.IsStartPosDefined)
|
||||
propVariant = item.StartPos;
|
||||
prop = item.StartPos;
|
||||
break;
|
||||
}
|
||||
case kpidPackedSize:
|
||||
{
|
||||
// propVariant = ref2.PackSize;
|
||||
// prop = ref2.PackSize;
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
||||
propVariant = _database.GetFolderFullPackSize(folderIndex);
|
||||
prop = _database.GetFolderFullPackSize(folderIndex);
|
||||
/*
|
||||
else
|
||||
propVariant = UInt64(0);
|
||||
prop = (UInt64)0;
|
||||
*/
|
||||
}
|
||||
else
|
||||
propVariant = UInt64(0);
|
||||
prop = (UInt64)0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidLastAccessTime:
|
||||
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
|
||||
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
|
||||
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
|
||||
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
|
||||
break;
|
||||
case kpidAttributes:
|
||||
if (item.AreAttributesDefined)
|
||||
propVariant = item.Attributes;
|
||||
prop = item.Attributes;
|
||||
break;
|
||||
case kpidCRC:
|
||||
if (item.IsFileCRCDefined)
|
||||
propVariant = item.FileCRC;
|
||||
prop = item.FileCRC;
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
{
|
||||
propVariant = IsEncrypted(index2);
|
||||
prop = IsEncrypted(index2);
|
||||
break;
|
||||
}
|
||||
#ifndef _SFX
|
||||
@@ -357,7 +390,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
}
|
||||
}
|
||||
propVariant = methodsString;
|
||||
prop = methodsString;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -365,7 +398,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
{
|
||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
propVariant = (UInt32)folderIndex;
|
||||
prop = (UInt32)folderIndex;
|
||||
}
|
||||
break;
|
||||
case kpidPackedSize0:
|
||||
@@ -381,21 +414,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
||||
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
||||
{
|
||||
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
}
|
||||
else
|
||||
propVariant = UInt64(0);
|
||||
prop = (UInt64)0;
|
||||
}
|
||||
else
|
||||
propVariant = UInt64(0);
|
||||
prop = (UInt64)0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case kpidIsAnti:
|
||||
propVariant = item.IsAnti;
|
||||
prop = item.IsAnti;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -522,11 +555,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
{
|
||||
UString baseName;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
break;
|
||||
baseName = propVariant.bstrVal;
|
||||
baseName = prop.bstrVal;
|
||||
}
|
||||
seqName.InitName(baseName);
|
||||
}
|
||||
|
||||
@@ -170,6 +170,13 @@ struct CArchiveDatabase
|
||||
NumUnPackStreamsVector.IsEmpty() &&
|
||||
Files.IsEmpty());
|
||||
}
|
||||
bool IsSolid() const
|
||||
{
|
||||
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
|
||||
if (NumUnPackStreamsVector[i] > 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -37,18 +37,14 @@ CPropMap kPropMap[] =
|
||||
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
|
||||
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
|
||||
|
||||
|
||||
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
|
||||
|
||||
{ NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL},
|
||||
{ NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
|
||||
// { 97, NULL, kpidSolid, VT_BOOL},
|
||||
#ifndef _SFX
|
||||
{ 98, NULL, kpidMethod, VT_BSTR},
|
||||
{ 99, L"Block", kpidBlock, VT_UI4}
|
||||
{ 99, NULL, kpidBlock, VT_UI4}
|
||||
#endif
|
||||
// { L"ID", kpidID, VT_BSTR},
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
// { L"Host OS", kpidHostOS, VT_BSTR}
|
||||
};
|
||||
|
||||
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
|
||||
|
||||
@@ -22,52 +22,19 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
||||
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
||||
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
|
||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
||||
{
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
}
|
||||
|
||||
static HRESULT WriteRange(
|
||||
ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
UInt64 size,
|
||||
IProgress *progress,
|
||||
UInt64 ¤tComplexity)
|
||||
{
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
streamSpec->SetStream(inStream);
|
||||
streamSpec->Init(size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(progress, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
|
||||
localCompressProgressSpec->Init(localProgress, ¤tComplexity, ¤tComplexity);
|
||||
|
||||
HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
|
||||
currentComplexity += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT WriteRange(IInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
UInt64 position,
|
||||
UInt64 size,
|
||||
IProgress *progress,
|
||||
UInt64 ¤tComplexity)
|
||||
{
|
||||
inStream->Seek(position, STREAM_SEEK_SET, 0);
|
||||
return WriteRange(inStream, outStream,
|
||||
size, progress, currentComplexity);
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
|
||||
return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
|
||||
}
|
||||
|
||||
static int GetReverseSlashPos(const UString &name)
|
||||
@@ -94,14 +61,6 @@ UString CUpdateItem::GetExtension() const
|
||||
return Name.Mid(GetExtensionPos());
|
||||
}
|
||||
|
||||
/*
|
||||
struct CFolderRef
|
||||
{
|
||||
const CArchiveDatabaseEx *Database;
|
||||
int FolderIndex;
|
||||
};
|
||||
*/
|
||||
|
||||
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||
|
||||
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
|
||||
@@ -522,16 +481,10 @@ static HRESULT Update2(
|
||||
return E_NOTIMPL;
|
||||
*/
|
||||
|
||||
UInt64 startBlockSize = database != 0 ?
|
||||
database->ArchiveInfo.StartPosition: 0;
|
||||
UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
|
||||
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
||||
{
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->SetStream(inStream);
|
||||
streamSpec->Init(startBlockSize);
|
||||
RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
|
||||
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
|
||||
}
|
||||
|
||||
CRecordVector<int> fileIndexToUpdateIndexMap;
|
||||
@@ -607,6 +560,11 @@ static HRESULT Update2(
|
||||
complexity = 0;
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(updateCallback, true);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Write Copy Items
|
||||
|
||||
@@ -614,10 +572,11 @@ static HRESULT Update2(
|
||||
{
|
||||
int folderIndex = folderRefs[i];
|
||||
|
||||
lps->ProgressOffset = complexity;
|
||||
UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
|
||||
RINOK(WriteRange(inStream, archive.SeqStream,
|
||||
database->GetFolderStreamPos(folderIndex, 0),
|
||||
database->GetFolderFullPackSize(folderIndex),
|
||||
updateCallback, complexity));
|
||||
database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
|
||||
complexity += packSize;
|
||||
|
||||
const CFolder &folder = database->Folders[folderIndex];
|
||||
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
|
||||
@@ -736,18 +695,17 @@ static HRESULT Update2(
|
||||
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
|
||||
|
||||
CFolder folderItem;
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
|
||||
int startPackIndex = newDatabase.PackSizes.Size();
|
||||
RINOK(encoder.Encode(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
solidInStream, NULL, &inSizeForReduce, folderItem,
|
||||
archive.SeqStream, newDatabase.PackSizes, compressProgress));
|
||||
archive.SeqStream, newDatabase.PackSizes, progress));
|
||||
|
||||
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
|
||||
lps->OutSize += newDatabase.PackSizes[startPackIndex];
|
||||
|
||||
lps->InSize += folderItem.GetUnPackSize();
|
||||
// for()
|
||||
// newDatabase.PackCRCsDefined.Add(false);
|
||||
// newDatabase.PackCRCs.Add(0);
|
||||
@@ -783,7 +741,6 @@ static HRESULT Update2(
|
||||
file.IsFileCRCDefined = true;
|
||||
file.HasStream = true;
|
||||
numUnPackStreams++;
|
||||
complexity += file.UnPackSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -935,8 +892,7 @@ HRESULT UpdateVolume(
|
||||
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
|
||||
inCrcStreamSpec->Init(fileStream);
|
||||
|
||||
RINOK(WriteRange(inCrcStream, volumeStream, pureSize,
|
||||
updateCallback, complexity));
|
||||
RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
|
||||
file.UnPackSize = inCrcStreamSpec->GetSize();
|
||||
if (file.UnPackSize == 0)
|
||||
break;
|
||||
|
||||
@@ -85,11 +85,11 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
||||
if (formatIndex >= g_NumArcs)
|
||||
return E_INVALIDARG;
|
||||
const CArcInfo &arc = *g_Arcs[formatIndex];
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
propVariant = arc.Name;
|
||||
prop = arc.Name;
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
@@ -99,22 +99,22 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
if (arc.Ext != 0)
|
||||
propVariant = arc.Ext;
|
||||
prop = arc.Ext;
|
||||
break;
|
||||
case NArchive::kAddExtension:
|
||||
if (arc.AddExt != 0)
|
||||
propVariant = arc.AddExt;
|
||||
prop = arc.AddExt;
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = (bool)(arc.CreateOutArchive != 0);
|
||||
prop = (bool)(arc.CreateOutArchive != 0);
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = arc.KeepName;
|
||||
prop = arc.KeepName;
|
||||
break;
|
||||
case NArchive::kStartSignature:
|
||||
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,16 +51,7 @@ const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidHostOS = kpidUserDefined,
|
||||
kpidUnPackVersion,
|
||||
kpidMethod,
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -68,59 +59,15 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
|
||||
{ NULL, kpidEncrypted, VT_BOOL},
|
||||
// { NULL, kpidCommented, VT_BOOL},
|
||||
|
||||
{ NULL, kpidCRC, VT_UI4},
|
||||
|
||||
{ NULL, kpidMethod, VT_UI1},
|
||||
// { NULL, kpidUnpackVer, VT_UI1},
|
||||
{ NULL, kpidHostOS, VT_BSTR}
|
||||
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
// { L"Method", kpidMethod, VT_UI1},
|
||||
// { L"Host OS", kpidHostOS, VT_BSTR}
|
||||
};
|
||||
|
||||
|
||||
CHandler::CHandler()
|
||||
{}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
@@ -131,27 +78,19 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant =
|
||||
NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
/*
|
||||
NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
|
||||
*/
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.Size;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = item.PackSize;
|
||||
break;
|
||||
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
||||
case kpidIsFolder: prop = item.IsDirectory(); break;
|
||||
case kpidSize: prop = item.Size; break;
|
||||
case kpidPackedSize: prop = item.PackSize; break;
|
||||
case kpidAttributes: prop = item.GetWinAttributes(); break;
|
||||
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
||||
case kpidCRC: prop = item.FileCRC; break;
|
||||
case kpidMethod: prop = item.Method; break;
|
||||
case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
@@ -162,52 +101,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = item.GetWinAttributes();
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
propVariant = item.IsEncrypted();
|
||||
break;
|
||||
/*
|
||||
case kpidCommented:
|
||||
propVariant = item.IsCommented();
|
||||
break;
|
||||
*/
|
||||
case kpidCRC:
|
||||
propVariant = item.FileCRC;
|
||||
break;
|
||||
case kpidMethod:
|
||||
propVariant = item.Method;
|
||||
break;
|
||||
case kpidHostOS:
|
||||
propVariant = (item.HostOS < kNumHostOSes) ?
|
||||
(kHostOS[item.HostOS]) : kUnknownOS;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
/*
|
||||
class CPropgressImp: public CProgressVirt
|
||||
{
|
||||
public:
|
||||
CMyComPtr<IArchiveOpenCallback> Callback;
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
||||
};
|
||||
|
||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
||||
{
|
||||
if (Callback)
|
||||
return Callback->SetCompleted(numFiles, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
||||
{
|
||||
@@ -226,17 +128,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
CItemEx itemInfo;
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, itemInfo);
|
||||
HRESULT result = archive.GetNextItem(filled, item);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(itemInfo);
|
||||
archive.IncreaseRealPosition(itemInfo.PackSize);
|
||||
_items.Add(item);
|
||||
archive.IncreaseRealPosition(item.PackSize);
|
||||
if (callback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
@@ -279,9 +181,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += itemInfo.Size;
|
||||
totalPacked += itemInfo.PackSize;
|
||||
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += item.Size;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
|
||||
@@ -290,29 +192,40 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_stream);
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
{
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
currentItemUnPacked = currentItemPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = _items[index];
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if(itemInfo.IsDirectory())
|
||||
if(item.IsDirectory())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -321,8 +234,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
currentItemUnPacked = itemInfo.Size;
|
||||
currentItemPacked = itemInfo.PackSize;
|
||||
currentItemUnPacked = item.Size;
|
||||
currentItemPacked = item.PackSize;
|
||||
|
||||
{
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
@@ -331,149 +244,63 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
outStreamSpec->Init();
|
||||
realOutStream.Release();
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->Init(item.PackSize);
|
||||
|
||||
UInt64 pos;
|
||||
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
|
||||
streamSpec->SetStream(_stream);
|
||||
streamSpec->Init(itemInfo.PackSize);
|
||||
HRESULT result = S_OK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalPacked,
|
||||
¤tTotalUnPacked);
|
||||
|
||||
if (itemInfo.IsEncrypted())
|
||||
if (item.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
}
|
||||
|
||||
HRESULT result;
|
||||
|
||||
switch(itemInfo.Method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
{
|
||||
if(!copyCoder)
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
try
|
||||
{
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = copyCoder->Code(inStream, outStream,
|
||||
NULL, NULL, compressProgress);
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
||||
{
|
||||
if(!arj1Decoder)
|
||||
{
|
||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = arj1Decoder->Code(inStream, outStream,
|
||||
NULL, ¤tItemUnPacked, compressProgress);
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
||||
{
|
||||
if(!arj2Decoder)
|
||||
{
|
||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (itemInfo.IsEncrypted())
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = arj2Decoder->Code(inStream, outStream,
|
||||
NULL, ¤tItemUnPacked, compressProgress);
|
||||
}
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC;
|
||||
outStream.Release();
|
||||
if(crcOK)
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
||||
else
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
|
||||
{
|
||||
switch(item.Method)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kStored:
|
||||
{
|
||||
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
|
||||
result = S_FALSE;
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
||||
{
|
||||
if (!arj1Decoder)
|
||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
||||
result = arj1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
||||
break;
|
||||
}
|
||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
||||
{
|
||||
if (!arj2Decoder)
|
||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
||||
result = arj2Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
}
|
||||
}
|
||||
if (opRes == NExtract::NOperationResult::kOK)
|
||||
{
|
||||
if (result == S_FALSE)
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
{
|
||||
RINOK(result);
|
||||
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
|
||||
NExtract::NOperationResult::kOK:
|
||||
NExtract::NOperationResult::kCRCError;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(opRes));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
@@ -19,7 +19,6 @@ public:
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
|
||||
CHandler();
|
||||
private:
|
||||
CObjectVector<CItemEx> _items;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
|
||||
@@ -21,49 +21,13 @@ namespace NBZip2 {
|
||||
|
||||
static const CMethodId kMethodId_BZip2 = 0x040202;
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
// { NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
@@ -71,24 +35,15 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
if (index != 0)
|
||||
return E_INVALIDARG;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = _item.PackSize;
|
||||
break;
|
||||
case kpidPackedSize: prop = _item.PackSize; break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
@@ -148,14 +103,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
extractCallback->SetTotal(_item.PackSize);
|
||||
|
||||
UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0;
|
||||
UInt64 currentTotalPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
askMode = testMode ? NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
|
||||
@@ -171,7 +126,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
kMethodId_BZip2, decoder, false);
|
||||
if (loadResult != S_OK || !decoder)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -188,29 +143,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init(realOutStream);
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
outStreamSpec->Init();
|
||||
|
||||
realOutStream.Release();
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, true);
|
||||
|
||||
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
|
||||
|
||||
|
||||
HRESULT result = S_OK;
|
||||
|
||||
bool firstItem = true;
|
||||
for (;;)
|
||||
{
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalPacked,
|
||||
¤tTotalUnPacked);
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = outStreamSpec->GetSize();
|
||||
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
const int kSignatureSize = 3;
|
||||
Byte buffer[kSignatureSize];
|
||||
@@ -226,26 +178,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
if (firstItem)
|
||||
return E_FAIL;
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
||||
return S_OK;
|
||||
break;
|
||||
}
|
||||
firstItem = false;
|
||||
|
||||
UInt64 dataStartPos;
|
||||
RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos));
|
||||
|
||||
result = decoder->Code(_stream, outStream, NULL, NULL, compressProgress);
|
||||
result = decoder->Code(_stream, outStream, NULL, NULL, progress);
|
||||
|
||||
if (result != S_OK)
|
||||
break;
|
||||
|
||||
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
|
||||
decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
|
||||
&getInStreamProcessedSize);
|
||||
decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize);
|
||||
if (!getInStreamProcessedSize)
|
||||
break;
|
||||
|
||||
UInt64 packSize;
|
||||
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
|
||||
UInt64 pos;
|
||||
@@ -254,17 +202,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
outStream.Release();
|
||||
|
||||
int retResult;
|
||||
Int32 retResult;
|
||||
if (result == S_OK)
|
||||
retResult = NArchive::NExtract::NOperationResult::kOK;
|
||||
retResult = NExtract::NOperationResult::kOK;
|
||||
else if (result == S_FALSE)
|
||||
retResult = NArchive::NExtract::NOperationResult::kDataError;
|
||||
retResult = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
return result;
|
||||
return extractCallback->SetOperationResult(retResult);
|
||||
|
||||
RINOK(extractCallback->SetOperationResult(retResult));
|
||||
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -49,20 +49,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
UInt32 indexInArchive;
|
||||
if (!updateCallback)
|
||||
return E_FAIL;
|
||||
RINOK(updateCallback->GetUpdateItemInfo(0,
|
||||
&newData, &newProperties, &indexInArchive));
|
||||
RINOK(updateCallback->GetUpdateItemInfo(0,&newData, &newProperties, &indexInArchive));
|
||||
|
||||
if (IntToBool(newProperties))
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_BOOL)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop));
|
||||
if (prop.vt == VT_BOOL)
|
||||
{
|
||||
if (propVariant.boolVal != VARIANT_FALSE)
|
||||
if (prop.boolVal != VARIANT_FALSE)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else if (propVariant.vt != VT_EMPTY)
|
||||
else if (prop.vt != VT_EMPTY)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
@@ -71,11 +70,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
{
|
||||
UInt64 size;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
|
||||
UInt32 dicSize = _dicSize;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "CabHandler.h"
|
||||
#include "CabBlockInStream.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
#include "../../Compress/Deflate/DeflateDecoder.h"
|
||||
#include "../../Compress/Lzx/LzxDecoder.h"
|
||||
@@ -31,13 +33,11 @@ namespace NCab {
|
||||
#ifdef _CAB_DETAILS
|
||||
enum
|
||||
{
|
||||
kpidBlockReal = kpidUserDefined,
|
||||
kpidOffset,
|
||||
kpidVolume,
|
||||
kpidBlockReal = kpidUserDefined
|
||||
};
|
||||
#endif
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -49,8 +49,8 @@ STATPROPSTG kProperties[] =
|
||||
#ifdef _CAB_DETAILS
|
||||
,
|
||||
{ L"BlockReal", kpidBlockReal, VT_UI4},
|
||||
{ L"Offset", kpidOffset, VT_UI4},
|
||||
{ L"Volume", kpidVolume, VT_UI4}
|
||||
{ NULL, kpidOffset, VT_UI4},
|
||||
{ NULL, kpidVolume, VT_UI4}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -65,49 +65,69 @@ static const wchar_t *kMethods[] =
|
||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
// { NULL, kpidSolid, VT_BOOL},
|
||||
{ NULL, kpidNumBlocks, VT_UI4},
|
||||
{ NULL, kpidNumVolumes, VT_UI4}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
if (srcItem.lpwstrName == 0)
|
||||
*name = 0;
|
||||
else
|
||||
*name = ::SysAllocString(srcItem.lpwstrName);
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidMethod:
|
||||
{
|
||||
UString resString;
|
||||
CRecordVector<Byte> ids;
|
||||
int i;
|
||||
for (int v = 0; v < m_Database.Volumes.Size(); v++)
|
||||
{
|
||||
const CDatabaseEx &de = m_Database.Volumes[v];
|
||||
for (i = 0; i < de.Folders.Size(); i++)
|
||||
ids.AddToUniqueSorted(de.Folders[i].GetCompressionMethod());
|
||||
}
|
||||
for (i = 0; i < ids.Size(); i++)
|
||||
{
|
||||
Byte id = ids[i];
|
||||
UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
|
||||
if (!resString.IsEmpty())
|
||||
resString += L' ';
|
||||
resString += method;
|
||||
}
|
||||
prop = resString;
|
||||
break;
|
||||
}
|
||||
// case kpidSolid: prop = _database.IsSolid(); break;
|
||||
case kpidNumBlocks:
|
||||
{
|
||||
UInt32 numFolders = 0;
|
||||
for (int v = 0; v < m_Database.Volumes.Size(); v++)
|
||||
numFolders += m_Database.Volumes[v].Folders.Size();
|
||||
prop = numFolders;
|
||||
break;
|
||||
}
|
||||
case kpidNumVolumes:
|
||||
{
|
||||
prop = (UInt32)m_Database.Volumes.Size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
|
||||
const CMvItem &mvItem = m_Database.Items[index];
|
||||
const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex];
|
||||
@@ -122,14 +142,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
ConvertUTF8ToUnicode(item.Name, unicodeName);
|
||||
else
|
||||
unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP);
|
||||
propVariant = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
|
||||
prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.Size;
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -141,11 +161,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = item.GetWinAttributes();
|
||||
prop = item.GetWinAttributes();
|
||||
break;
|
||||
|
||||
case kpidMethod:
|
||||
@@ -162,28 +182,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
||||
method += temp;
|
||||
}
|
||||
propVariant = method;
|
||||
prop = method;
|
||||
break;
|
||||
}
|
||||
case kpidBlock:
|
||||
propVariant = (Int32)m_Database.GetFolderIndex(&mvItem);
|
||||
prop = (Int32)m_Database.GetFolderIndex(&mvItem);
|
||||
break;
|
||||
|
||||
#ifdef _CAB_DETAILS
|
||||
|
||||
case kpidBlockReal:
|
||||
propVariant = UInt32(item.FolderIndex);
|
||||
prop = UInt32(item.FolderIndex);
|
||||
break;
|
||||
case kpidOffset:
|
||||
propVariant = (UInt32)item.Offset;
|
||||
prop = (UInt32)item.Offset;
|
||||
break;
|
||||
case kpidVolume:
|
||||
propVariant = (UInt32)mvItem.VolumeIndex;
|
||||
prop = (UInt32)mvItem.VolumeIndex;
|
||||
break;
|
||||
|
||||
#endif
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -568,8 +588,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
totalUnPacked = 0;
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
UInt64 totalPacked = 0;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> deflateDecoder;
|
||||
@@ -648,7 +674,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
curUnpack = item.GetEndOffset();
|
||||
}
|
||||
|
||||
RINOK(extractCallback->SetCompleted(&totalUnPacked));
|
||||
lps->OutSize = totalUnPacked;
|
||||
lps->InSize = totalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
|
||||
@@ -662,11 +690,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
switch(folder.GetCompressionMethod())
|
||||
{
|
||||
case NHeader::NCompressionMethodMajor::kNone:
|
||||
if(copyCoderSpec == NULL)
|
||||
{
|
||||
copyCoderSpec = new NCompress::CCopyCoder;
|
||||
copyCoder = copyCoderSpec;
|
||||
}
|
||||
break;
|
||||
case NHeader::NCompressionMethodMajor::kMSZip:
|
||||
if(deflateDecoderSpec == NULL)
|
||||
@@ -748,9 +771,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (keepInputBuffer)
|
||||
continue;
|
||||
|
||||
|
||||
UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder();
|
||||
RINOK(extractCallback->SetCompleted(&totalUnPacked2));
|
||||
totalPacked += packSize;
|
||||
|
||||
lps->OutSize = totalUnPacked2;
|
||||
lps->InSize = totalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
UInt64 unpackRemain = cabFolderOutStream->GetRemain();
|
||||
|
||||
const UInt32 kBlockSizeMax = (1 << 15);
|
||||
|
||||
@@ -34,13 +34,12 @@ namespace NChm {
|
||||
|
||||
enum
|
||||
{
|
||||
kpidSection = kpidUserDefined,
|
||||
kpidOffset
|
||||
kpidSection = kpidUserDefined
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -51,62 +50,63 @@ STATPROPSTG kProperties[] =
|
||||
#ifdef _CHM_DETAILS
|
||||
,
|
||||
{ L"Section", kpidSection, VT_UI4},
|
||||
{ L"Offset", kpidOffset, VT_UI4}
|
||||
{ NULL, kpidOffset, VT_UI4}
|
||||
#endif
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
{ NULL, kpidNumBlocks, VT_UI8}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
if (srcItem.lpwstrName == 0)
|
||||
*name = 0;
|
||||
else
|
||||
*name = ::SysAllocString(srcItem.lpwstrName);
|
||||
return S_OK;
|
||||
}
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
/*
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
*numProperties = 0;
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidNumBlocks:
|
||||
{
|
||||
UInt64 numBlocks = 0;
|
||||
for (int i = 0; i < m_Database.Sections.Size(); i++)
|
||||
{
|
||||
const CSectionInfo &s = m_Database.Sections[i];
|
||||
for (int j = 0; j < s.Methods.Size(); j++)
|
||||
{
|
||||
const CMethodInfo &m = s.Methods[j];
|
||||
if (m.IsLzx())
|
||||
numBlocks += m.LzxInfo.ResetTable.GetNumBlocks();
|
||||
}
|
||||
}
|
||||
prop = numBlocks;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
if (m_Database.NewFormat)
|
||||
{
|
||||
switch(propID)
|
||||
{
|
||||
case kpidSize:
|
||||
propVariant = (UInt64)m_Database.NewFormatString.Length();
|
||||
prop = (UInt64)m_Database.NewFormatString.Length();
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
int entryIndex;
|
||||
@@ -128,44 +128,44 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
if (us[0] == L'/')
|
||||
us.Delete(0);
|
||||
}
|
||||
propVariant = NItemName::GetOSName2(us);
|
||||
prop = NItemName::GetOSName2(us);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.Size;
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidMethod:
|
||||
{
|
||||
if (!item.IsDirectory())
|
||||
if (item.Section == 0)
|
||||
propVariant = L"Copy";
|
||||
prop = L"Copy";
|
||||
else if (item.Section < m_Database.Sections.Size())
|
||||
propVariant = m_Database.Sections[(int)item.Section].GetMethodName();
|
||||
prop = m_Database.Sections[(int)item.Section].GetMethodName();
|
||||
break;
|
||||
}
|
||||
case kpidBlock:
|
||||
if (m_Database.LowLevel)
|
||||
propVariant = item.Section;
|
||||
prop = item.Section;
|
||||
else if (item.Section != 0)
|
||||
propVariant = m_Database.GetFolder(index);
|
||||
prop = m_Database.GetFolder(index);
|
||||
break;
|
||||
|
||||
#ifdef _CHM_DETAILS
|
||||
|
||||
case kpidSection:
|
||||
propVariant = (UInt32)item.Section;
|
||||
prop = (UInt32)item.Section;
|
||||
break;
|
||||
case kpidOffset:
|
||||
propVariant = (UInt32)item.Offset;
|
||||
prop = (UInt32)item.Offset;
|
||||
break;
|
||||
|
||||
#endif
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -295,7 +295,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
||||
{
|
||||
if (m_FileIsOpen)
|
||||
return S_OK;
|
||||
for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
||||
for (;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
|
||||
{
|
||||
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
|
||||
if (fileSize != 0)
|
||||
@@ -421,17 +421,23 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
(m_Database.LowLevel ?
|
||||
m_Database.Items.Size():
|
||||
m_Database.Indices.Size());
|
||||
if(numItems == 0)
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
UInt32 i;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(m_Stream);
|
||||
|
||||
if (m_Database.LowLevel)
|
||||
{
|
||||
@@ -440,17 +446,21 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
if (m_Database.NewFormat)
|
||||
totalSize = m_Database.NewFormatString.Length();
|
||||
else
|
||||
for(i = 0; i < numItems; i++)
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size;
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
currentItemSize = 0;
|
||||
lps->InSize = currentTotalSize; // Change it
|
||||
lps->OutSize = currentTotalSize;
|
||||
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 askMode= testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
@@ -458,7 +468,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
if (index != 0)
|
||||
return E_FAIL;
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
if (!testMode)
|
||||
{
|
||||
@@ -472,7 +482,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
currentItemSize = item.Size;
|
||||
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (item.Section != 0)
|
||||
@@ -488,28 +498,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
|
||||
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->SetStream(m_Stream);
|
||||
streamSpec->Init(item.Size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize);
|
||||
|
||||
if(!copyCoder)
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
UInt64 lastFolderIndex = ((UInt64)0 - 1);
|
||||
for(i = 0; i < numItems; i++)
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
int entryIndex = m_Database.Indices[index];
|
||||
@@ -545,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
currentTotalSize = 0;
|
||||
|
||||
CRecordVector<bool> extractStatuses;
|
||||
for(i = 0; i < numItems;)
|
||||
for (i = 0; i < numItems;)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
@@ -566,32 +567,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
}
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress, NULL, ¤tTotalSize);
|
||||
lps->InSize = currentTotalSize; // Change it
|
||||
lps->OutSize = currentTotalSize;
|
||||
|
||||
if (item.Size == 0 || sectionIndex == 0)
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
if (!testMode && item.Size != 0)
|
||||
{
|
||||
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->SetStream(m_Stream);
|
||||
streamSpec->Init(item.Size);
|
||||
if(!copyCoder)
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize != item.Size)
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(opRes));
|
||||
currentTotalSize += item.Size;
|
||||
continue;
|
||||
}
|
||||
@@ -652,7 +648,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
chmFolderOutStream->m_StartIndex = index;
|
||||
if (limitFolderIndex == folderIndex)
|
||||
{
|
||||
for(; i < numItems; i++)
|
||||
for (; i < numItems; i++)
|
||||
{
|
||||
UInt32 nextIndex = allFilesMode ? i : indices[i];
|
||||
int entryIndex = m_Database.Indices[nextIndex];
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace NArchive {
|
||||
namespace NCom {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -21,49 +21,32 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
{ NULL, kpidClusterSize, VT_UI4}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
if (srcItem.lpwstrName == 0)
|
||||
*name = 0;
|
||||
else
|
||||
*name = ::SysAllocString(srcItem.lpwstrName);
|
||||
return S_OK;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
*numProperties = 0;
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CRef &ref = _db.Refs[index];
|
||||
const CItem &item = _db.Items[ref.Did];
|
||||
|
||||
@@ -72,21 +55,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
case kpidPath:
|
||||
{
|
||||
UString name = _db.GetItemPath(index);
|
||||
propVariant = name;
|
||||
prop = name;
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDir();
|
||||
prop = item.IsDir();
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
propVariant = item.CreationTime;
|
||||
prop = item.CreationTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
propVariant = item.LastWriteTime;
|
||||
prop = item.LastWriteTime;
|
||||
break;
|
||||
/*
|
||||
case kpidAttributes:
|
||||
propVariant = item.Falgs;
|
||||
prop = item.Falgs;
|
||||
break;
|
||||
*/
|
||||
case kpidPackedSize:
|
||||
@@ -95,15 +78,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
int numBits = _db.IsLargeStream(item.Size) ?
|
||||
_db.SectorSizeBits :
|
||||
_db.MiniSectorSizeBits;
|
||||
propVariant = (item.Size + ((UInt32)1 << numBits) - 1) >> numBits << numBits;
|
||||
prop = (item.Size + ((UInt64)1 << numBits) - 1) >> numBits << numBits;
|
||||
break;
|
||||
}
|
||||
case kpidSize:
|
||||
if (!item.IsDir())
|
||||
propVariant = (UInt64)item.Size;
|
||||
prop = (UInt64)item.Size;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ HRESULT OpenArchive(IInStream *inStream, CDatabase &db)
|
||||
if (!db.MiniSids.Allocate(numSectorsInMiniStream))
|
||||
return S_FALSE;
|
||||
{
|
||||
UInt64 matSize64 = (root.Size + (1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits;
|
||||
UInt64 matSize64 = (root.Size + ((UInt64)1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits;
|
||||
if (matSize64 > NFatID::kMaxValue)
|
||||
return S_FALSE;
|
||||
db.MatSize = (UInt32)matSize64;
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Com", L"msi doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 };
|
||||
{ L"Compound", L"msi doc xls ppt", 0, 0xE5, { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }, 8, false, CreateArc, 0 };
|
||||
|
||||
REGISTER_ARC(Com)
|
||||
|
||||
@@ -167,6 +167,14 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
|
||||
{
|
||||
for (int i = 0; i < _coders.Size(); i++)
|
||||
if (_coders[i].Result == code)
|
||||
return code;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 ** /* inSizes */,
|
||||
UInt32 numInStreams,
|
||||
@@ -198,18 +206,10 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
||||
if (i != _progressCoderIndex)
|
||||
_coders[i].WaitFinish();
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result == E_ABORT)
|
||||
return result;
|
||||
}
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result == S_FALSE)
|
||||
return result;
|
||||
}
|
||||
RINOK(ReturnIfError(E_ABORT));
|
||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
||||
RINOK(ReturnIfError(S_FALSE));
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
|
||||
@@ -51,6 +51,7 @@ class CCoderMixer2MT:
|
||||
|
||||
void AddCoderCommon();
|
||||
HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
|
||||
HRESULT ReturnIfError(HRESULT code);
|
||||
public:
|
||||
CObjectVector<CCoder2> _coders;
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
@@ -30,6 +30,14 @@ void CCoderMixerMT::ReInit()
|
||||
_coders[i].ReInit();
|
||||
}
|
||||
|
||||
HRESULT CCoderMixerMT::ReturnIfError(HRESULT code)
|
||||
{
|
||||
for (int i = 0; i < _coders.Size(); i++)
|
||||
if (_coders[i].Result == code)
|
||||
return code;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 * /* inSize */, const UInt64 * /* outSize */,
|
||||
@@ -67,18 +75,10 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
|
||||
if (i != _progressCoderIndex)
|
||||
_coders[i].WaitFinish();
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result == E_ABORT)
|
||||
return result;
|
||||
}
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result == S_FALSE)
|
||||
return result;
|
||||
}
|
||||
RINOK(ReturnIfError(E_ABORT));
|
||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
||||
RINOK(ReturnIfError(S_FALSE));
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
|
||||
@@ -42,6 +42,7 @@ class CCoderMixerMT:
|
||||
CObjectVector<CStreamBinder> _streamBinders;
|
||||
int _progressCoderIndex;
|
||||
|
||||
HRESULT ReturnIfError(HRESULT code);
|
||||
public:
|
||||
CObjectVector<CCoder> _coders;
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
@@ -4,17 +4,19 @@
|
||||
|
||||
#include "DummyOutStream.h"
|
||||
|
||||
void CDummyOutStream::Init(ISequentialOutStream *outStream)
|
||||
STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
m_Stream = outStream;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDummyOutStream::Write(const void *data,
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(m_Stream)
|
||||
return m_Stream->Write(data, size, processedSize);
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result;
|
||||
if(!_stream)
|
||||
{
|
||||
realProcessedSize = size;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
result = _stream->Write(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = size;
|
||||
return S_OK;
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ class CDummyOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
public:
|
||||
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
|
||||
void Init() { _size = 0; }
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
private:
|
||||
CMyComPtr<ISequentialOutStream> m_Stream;
|
||||
public:
|
||||
void Init(ISequentialOutStream *outStream);
|
||||
UInt64 GetSize() const { return _size; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CpioHandler.h"
|
||||
#include "CpioIn.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
@@ -16,8 +17,8 @@
|
||||
#include "../../Common//LimitedStreams.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
#include "CpioIn.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NTime;
|
||||
@@ -25,13 +26,15 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NCpio {
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidinode = kpidUserDefined,
|
||||
kpidiChkSum
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -44,43 +47,10 @@ STATPROPSTG kProperties[] =
|
||||
// { L"CheckSum", kpidiChkSum, VT_UI4}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
@@ -89,41 +59,41 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
{
|
||||
CInArchive archive;
|
||||
|
||||
if(archive.Open(inStream) != S_OK)
|
||||
if (archive.Open(stream) != S_OK)
|
||||
return S_FALSE;
|
||||
|
||||
m_Items.Clear();
|
||||
_items.Clear();
|
||||
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
|
||||
UInt64 numFiles = m_Items.Size();
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CItemEx itemInfo;
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, itemInfo);
|
||||
HRESULT result = archive.GetNextItem(filled, item);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
m_Items.Add(itemInfo);
|
||||
archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align);
|
||||
_items.Add(item);
|
||||
archive.SkeepDataRecords(item.Size, item.Align);
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
UInt64 numFiles = m_Items.Size();
|
||||
UInt64 numFiles = _items.Size();
|
||||
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
|
||||
}
|
||||
}
|
||||
if (m_Items.Size() == 0)
|
||||
if (_items.Size() == 0)
|
||||
return S_FALSE;
|
||||
|
||||
m_InStream = inStream;
|
||||
_inStream = stream;
|
||||
}
|
||||
/*
|
||||
catch(...)
|
||||
@@ -137,35 +107,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
m_Items.Clear();
|
||||
m_InStream.Release();
|
||||
_items.Clear();
|
||||
_inStream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = m_Items.Size();
|
||||
*numItems = _items.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
const CItemEx &item = m_Items[index];
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = (const wchar_t *)NItemName::GetOSName(
|
||||
prop = (const wchar_t *)NItemName::GetOSName(
|
||||
MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
propVariant = item.Size;
|
||||
prop = (UInt64)item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -177,19 +147,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
utcFileTime.dwLowDateTime = 0;
|
||||
utcFileTime.dwHighDateTime = 0;
|
||||
}
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidinode:
|
||||
propVariant = item.inode;
|
||||
break;
|
||||
/*
|
||||
case kpidinode:
|
||||
prop = item.inode;
|
||||
break;
|
||||
case kpidiChkSum:
|
||||
propVariant = item.ChkSum;
|
||||
prop = item.ChkSum;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -198,89 +168,65 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = m_Items.Size();
|
||||
if(numItems == 0)
|
||||
numItems = _items.Size();
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
totalSize += m_Items[allFilesMode ? i : indices[i]].Size;
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += _items[allFilesMode ? i : indices[i]].Size;
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize;
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = m_Items[index];
|
||||
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
currentItemSize = itemInfo.Size;
|
||||
|
||||
if(itemInfo.IsDirectory())
|
||||
currentItemSize = item.Size;
|
||||
if (item.IsDirectory())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
{
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(m_InStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(m_InStream);
|
||||
streamSpec->Init(itemInfo.Size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalSize, ¤tTotalSize);
|
||||
|
||||
if(copyCoder == NULL)
|
||||
{
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, realOutStream,
|
||||
NULL, NULL, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
}
|
||||
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -21,8 +21,8 @@ public:
|
||||
INTERFACE_IInArchive(;)
|
||||
|
||||
private:
|
||||
CObjectVector<CItemEx> m_Items;
|
||||
CMyComPtr<IInStream> m_InStream;
|
||||
CObjectVector<CItemEx> _items;
|
||||
CMyComPtr<IInStream> _inStream;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -26,51 +26,16 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NDeb {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
@@ -92,17 +57,17 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CItemEx itemInfo;
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, itemInfo);
|
||||
HRESULT result = archive.GetNextItem(filled, item);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(itemInfo);
|
||||
archive.SkeepData(itemInfo.Size);
|
||||
_items.Add(item);
|
||||
archive.SkeepData(item.Size);
|
||||
if (openArchiveCallback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
@@ -131,21 +96,21 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = (const wchar_t *)NItemName::GetOSName2(
|
||||
prop = (const wchar_t *)NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
propVariant = item.Size;
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -157,11 +122,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
utcFileTime.dwLowDateTime = 0;
|
||||
utcFileTime.dwHighDateTime = 0;
|
||||
}
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -170,83 +135,65 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (_aTestMode != 0);
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if(numItems == 0)
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
bool testMode = (_aTestMode != 0);
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += _items[allFilesMode ? i : indices[i]].Size;
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize;
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = _items[index];
|
||||
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
currentItemSize = item.Size;
|
||||
|
||||
currentItemSize = itemInfo.Size;
|
||||
|
||||
if(!testMode && (!realOutStream))
|
||||
|
||||
|
||||
|
||||
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
{
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(_inStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
streamSpec->Init(itemInfo.Size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalSize, ¤tTotalSize);
|
||||
|
||||
if(copyCoder == NULL)
|
||||
{
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, realOutStream,
|
||||
NULL, NULL, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
}
|
||||
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -59,15 +59,13 @@ enum // PropID
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
||||
// { NULL, kpidCommented, VT_BOOL},
|
||||
// { NULL, kpidMethod, VT_UI1},
|
||||
{ NULL, kpidHostOS, VT_BSTR},
|
||||
|
||||
@@ -77,39 +75,8 @@ STATPROPSTG kProperties[] =
|
||||
// { L"Is Text", kpidIsText, VT_BOOL},
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
const STATPROPSTG &prop = kProperties[index];
|
||||
*propID = prop.propid;
|
||||
*varType = prop.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
@@ -120,15 +87,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
if (m_Item.NameIsPresent())
|
||||
propVariant = MultiByteToUnicodeString(m_Item.Name, CP_ACP);
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP);
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -136,47 +100,47 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
|
||||
if (m_Item.Time != 0)
|
||||
{
|
||||
NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime);
|
||||
propVariant = utcTime;
|
||||
prop = utcTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0;
|
||||
// propVariant = utcTime;
|
||||
// prop = utcTime;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidSize:
|
||||
propVariant = UInt64(m_Item.UnPackSize32);
|
||||
prop = UInt64(m_Item.UnPackSize32);
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = m_PackSize;
|
||||
prop = m_PackSize;
|
||||
break;
|
||||
case kpidCommented:
|
||||
propVariant = m_Item.CommentIsPresent();
|
||||
prop = m_Item.CommentIsPresent();
|
||||
break;
|
||||
case kpidHostOS:
|
||||
propVariant = (m_Item.HostOS < kNumHostOSes) ?
|
||||
prop = (m_Item.HostOS < kNumHostOSes) ?
|
||||
kHostOS[m_Item.HostOS] : kUnknownOS;
|
||||
break;
|
||||
case kpidMethod:
|
||||
propVariant = m_Item.CompressionMethod;
|
||||
prop = m_Item.CompressionMethod;
|
||||
break;
|
||||
case kpidCRC:
|
||||
propVariant = m_Item.FileCRC;
|
||||
prop = m_Item.FileCRC;
|
||||
break;
|
||||
/*
|
||||
case kpidExtraFlags:
|
||||
propVariant = m_Item.ExtraFlags;
|
||||
prop = m_Item.ExtraFlags;
|
||||
break;
|
||||
case kpidIsText:
|
||||
propVariant = m_Item.IsText();
|
||||
prop = m_Item.IsText();
|
||||
break;
|
||||
case kpidExtraIsPresent:
|
||||
propVariant = m_Item.ExtraFieldIsPresent();
|
||||
prop = m_Item.ExtraFieldIsPresent();
|
||||
break;
|
||||
*/
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -232,7 +196,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
extractCallback->SetTotal(m_PackSize);
|
||||
|
||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UInt64 currentTotalPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
@@ -253,22 +217,18 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
outStreamSpec->Init();
|
||||
realOutStream.Release();
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, true);
|
||||
|
||||
CMyComPtr<ICompressCoder> deflateDecoder;
|
||||
bool firstItem = true;
|
||||
RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
|
||||
Int32 opRes;
|
||||
for (;;)
|
||||
{
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalPacked,
|
||||
¤tTotalUnPacked);
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = outStreamSpec->GetSize();
|
||||
|
||||
CInArchive archive;
|
||||
CItem item;
|
||||
@@ -277,9 +237,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
if (firstItem)
|
||||
return E_FAIL;
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
||||
return S_OK;
|
||||
opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
break;
|
||||
}
|
||||
firstItem = false;
|
||||
|
||||
@@ -288,45 +247,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
outStreamSpec->InitCRC();
|
||||
|
||||
switch(item.CompressionMethod)
|
||||
if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflate)
|
||||
{
|
||||
case NFileHeader::NCompressionMethod::kDeflate:
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!deflateDecoder)
|
||||
{
|
||||
RINOK(CreateCoder(
|
||||
EXTERNAL_CODECS_VARS
|
||||
kMethodId_Deflate, deflateDecoder, false));
|
||||
if (!deflateDecoder)
|
||||
{
|
||||
if(!deflateDecoder)
|
||||
{
|
||||
RINOK(CreateCoder(
|
||||
EXTERNAL_CODECS_VARS
|
||||
kMethodId_Deflate, deflateDecoder, false));
|
||||
if (!deflateDecoder)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
HRESULT result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, compressProgress);
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
return S_OK;
|
||||
}
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(
|
||||
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
return S_OK;
|
||||
}
|
||||
result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, progress);
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (result != S_FALSE)
|
||||
return result;
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
|
||||
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
|
||||
RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
|
||||
&getInStreamProcessedSize));
|
||||
@@ -342,12 +288,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
return E_FAIL;
|
||||
if((outStreamSpec->GetCRC() != postItem.FileCRC))
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
|
||||
opRes = NArchive::NExtract::NOperationResult::kCRCError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
return extractCallback->SetOperationResult(opRes);
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IMPL_ISetCompressCodecsInfo
|
||||
|
||||
@@ -70,41 +70,41 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
UString name;
|
||||
bool isDirectory;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
attributes = 0;
|
||||
else if (propVariant.vt != VT_UI4)
|
||||
else if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
attributes = propVariant.ulVal;
|
||||
attributes = prop.ulVal;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &propVariant));
|
||||
if (propVariant.vt != VT_FILETIME)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &prop));
|
||||
if (prop.vt != VT_FILETIME)
|
||||
return E_INVALIDARG;
|
||||
utcTime = propVariant.filetime;
|
||||
utcTime = prop.filetime;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
name.Empty();
|
||||
else if (propVariant.vt != VT_BSTR)
|
||||
else if (prop.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
name = propVariant.bstrVal;
|
||||
name = prop.bstrVal;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
isDirectory = false;
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
else if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
isDirectory = (propVariant.boolVal != VARIANT_FALSE);
|
||||
isDirectory = (prop.boolVal != VARIANT_FALSE);
|
||||
}
|
||||
if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes))
|
||||
return E_INVALIDARG;
|
||||
@@ -121,11 +121,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (IntToBool(newData))
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
newItem.UnPackSize32 = (UInt32)size;
|
||||
|
||||
|
||||
@@ -34,9 +34,7 @@ HRESULT UpdateArchive(
|
||||
int indexInClient,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
UInt64 complexity = 0;
|
||||
|
||||
complexity += unpackSize;
|
||||
UInt64 complexity = unpackSize;
|
||||
|
||||
RINOK(updateCallback->SetTotal(complexity));
|
||||
|
||||
@@ -54,13 +52,9 @@ HRESULT UpdateArchive(
|
||||
inStreamSpec->SetStream(fileInStream);
|
||||
inStreamSpec->Init();
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(updateCallback, true);
|
||||
|
||||
COutArchive outArchive;
|
||||
outArchive.Create(outStream);
|
||||
@@ -72,8 +66,6 @@ HRESULT UpdateArchive(
|
||||
|
||||
RINOK(outArchive.WriteHeader(item));
|
||||
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
|
||||
{
|
||||
RINOK(CreateCoder(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
@@ -102,7 +94,7 @@ HRESULT UpdateArchive(
|
||||
RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
|
||||
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));
|
||||
}
|
||||
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress));
|
||||
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
|
||||
|
||||
item.FileCRC = inStreamSpec->GetCRC();
|
||||
item.UnPackSize32 = (UInt32)inStreamSpec->GetSize();
|
||||
|
||||
@@ -7,12 +7,7 @@
|
||||
#include "../IProgress.h"
|
||||
#include "../PropID.h"
|
||||
|
||||
// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000")
|
||||
#define ARCHIVE_INTERFACE_SUB(i, base, x) \
|
||||
DEFINE_GUID(IID_ ## i, \
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00); \
|
||||
struct i: public base
|
||||
|
||||
#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
|
||||
#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
|
||||
|
||||
namespace NFileTimeType
|
||||
@@ -172,4 +167,41 @@ ARCHIVE_INTERFACE(ISetProperties, 0x03)
|
||||
};
|
||||
|
||||
|
||||
#define IMP_IInArchive_GetProp(k) \
|
||||
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
|
||||
{ if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
|
||||
const STATPROPSTG &srcItem = k[index]; \
|
||||
*propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
|
||||
|
||||
#define IMP_IInArchive_GetProp_WITH_NAME(k) \
|
||||
(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
|
||||
{ if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
|
||||
const STATPROPSTG &srcItem = k[index]; \
|
||||
*propID = srcItem.propid; *varType = srcItem.vt; \
|
||||
if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
|
||||
|
||||
#define IMP_IInArchive_Props \
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
|
||||
|
||||
#define IMP_IInArchive_Props_WITH_NAME \
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
|
||||
|
||||
|
||||
#define IMP_IInArchive_ArcProps \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
|
||||
|
||||
#define IMP_IInArchive_ArcProps_NO \
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
|
||||
{ *numProperties = 0; return S_OK; } \
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
|
||||
{ return E_NOTIMPL; } \
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
|
||||
{ value->vt = VT_EMPTY; return S_OK; }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
@@ -25,7 +26,7 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NIso {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -34,41 +35,8 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
@@ -103,7 +71,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
if (index >= (UInt32)_archive.Refs.Size())
|
||||
{
|
||||
index -= _archive.Refs.Size();
|
||||
@@ -118,16 +86,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
// s += name;
|
||||
// s += L"-";
|
||||
s += be.GetName();
|
||||
propVariant = (const wchar_t *)s;
|
||||
prop = (const wchar_t *)s;
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
{
|
||||
propVariant = (UInt64)_archive.GetBootItemSize(index);
|
||||
prop = (UInt64)_archive.GetBootItemSize(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -154,22 +122,22 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
if (!s.IsEmpty())
|
||||
if (s[s.Length() - 1] == L'.')
|
||||
s = s.Left(s.Length() - 1);
|
||||
propVariant = (const wchar_t *)NItemName::GetOSName2(s);
|
||||
prop = (const wchar_t *)NItemName::GetOSName2(s);
|
||||
}
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDir();
|
||||
prop = item.IsDir();
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
if (!item.IsDir())
|
||||
propVariant = (UInt64)item.DataLength;
|
||||
prop = (UInt64)item.DataLength;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME utcFileTime;
|
||||
if (item.DateTime.GetFileTime(utcFileTime))
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
/*
|
||||
else
|
||||
{
|
||||
@@ -181,7 +149,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
}
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -194,9 +162,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _archive.Refs.Size();
|
||||
UInt64 totalSize = 0;
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
@@ -217,12 +185,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize;
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
currentItemSize = 0;
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
|
||||
@@ -252,47 +230,21 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
blockIndex = be.LoadRBA;
|
||||
}
|
||||
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
streamSpec->Init(currentItemSize);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize);
|
||||
|
||||
Int32 res = NArchive::NExtract::NOperationResult::kOK;
|
||||
if(!copyCoder)
|
||||
{
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
res = NArchive::NExtract::NOperationResult::kDataError;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(res));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(currentItemSize);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -67,7 +67,7 @@ static const wchar_t *GetOS(Byte osId)
|
||||
return kUnknownOS;
|
||||
};
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -85,45 +85,10 @@ STATPROPSTG kProperties[] =
|
||||
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
CHandler::CHandler()
|
||||
{}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
CHandler::CHandler() {}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
@@ -134,7 +99,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
switch(propID)
|
||||
{
|
||||
@@ -145,18 +110,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
{
|
||||
if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR)
|
||||
s.Delete(s.Length() - 1);
|
||||
propVariant = s;
|
||||
prop = s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.Size;
|
||||
prop = item.Size;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = item.PackSize;
|
||||
prop = item.PackSize;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -177,19 +142,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case kpidAttributes:
|
||||
propVariant = (UInt32)item.Attributes;
|
||||
prop = (UInt32)item.Attributes;
|
||||
break;
|
||||
case kpidCommented:
|
||||
propVariant = item.IsCommented();
|
||||
prop = item.IsCommented();
|
||||
break;
|
||||
*/
|
||||
case kpidCRC:
|
||||
propVariant = (UInt32)item.CRC;
|
||||
prop = (UInt32)item.CRC;
|
||||
break;
|
||||
case kpidMethod:
|
||||
{
|
||||
@@ -197,14 +162,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
method2[kMethodIdSize] = 0;
|
||||
for (int i = 0; i < kMethodIdSize; i++)
|
||||
method2[i] = item.Method[i];
|
||||
propVariant = method2;
|
||||
prop = method2;
|
||||
break;
|
||||
}
|
||||
case kpidHostOS:
|
||||
propVariant = GetOS(item.OsId);
|
||||
prop = GetOS(item.OsId);
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -242,17 +207,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
CItemEx itemInfo;
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
HRESULT result = archive.GetNextItem(filled, itemInfo);
|
||||
HRESULT result = archive.GetNextItem(filled, item);
|
||||
if (result == S_FALSE)
|
||||
return S_FALSE;
|
||||
if (result != S_OK)
|
||||
return S_FALSE;
|
||||
if (!filled)
|
||||
break;
|
||||
_items.Add(itemInfo);
|
||||
archive.Skeep(itemInfo.PackSize);
|
||||
_items.Add(item);
|
||||
archive.Skeep(item.PackSize);
|
||||
if (callback != NULL)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
@@ -298,9 +263,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
{
|
||||
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += itemInfo.Size;
|
||||
totalPacked += itemInfo.PackSize;
|
||||
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
||||
totalUnPacked += item.Size;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
|
||||
@@ -311,7 +276,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
CMyComPtr<ICompressCoder> lzhDecoder;
|
||||
CMyComPtr<ICompressCoder> lzh1Decoder;
|
||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_stream);
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
@@ -319,21 +294,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
askMode = testMode ? NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &itemInfo = _items[index];
|
||||
const CItemEx &item = _items[index];
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
if(itemInfo.IsDirectory())
|
||||
if(item.IsDirectory())
|
||||
{
|
||||
// if (!testMode)
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -342,8 +320,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
currentItemUnPacked = itemInfo.Size;
|
||||
currentItemPacked = itemInfo.PackSize;
|
||||
currentItemUnPacked = item.Size;
|
||||
currentItemPacked = item.PackSize;
|
||||
|
||||
{
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
@@ -351,109 +329,58 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
outStreamSpec->Init(realOutStream);
|
||||
realOutStream.Release();
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
|
||||
UInt64 pos;
|
||||
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
|
||||
|
||||
streamSpec->SetStream(_stream);
|
||||
streamSpec->Init(itemInfo.PackSize);
|
||||
streamSpec->Init(item.PackSize);
|
||||
|
||||
HRESULT result = S_OK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalPacked,
|
||||
¤tTotalUnPacked);
|
||||
|
||||
HRESULT result;
|
||||
|
||||
if (itemInfo.IsCopyMethod())
|
||||
if (item.IsCopyMethod())
|
||||
{
|
||||
if(!copyCoder)
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
try
|
||||
{
|
||||
result = copyCoder->Code(inStream, outStream, NULL, NULL, compressProgress);
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
|
||||
result = S_FALSE;
|
||||
}
|
||||
else if (itemInfo.IsLh4GroupMethod())
|
||||
else if (item.IsLh4GroupMethod())
|
||||
{
|
||||
if(!lzhDecoder)
|
||||
{
|
||||
lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder;
|
||||
lzhDecoder = lzhDecoderSpec;
|
||||
}
|
||||
try
|
||||
{
|
||||
lzhDecoderSpec->SetDictionary(itemInfo.GetNumDictBits());
|
||||
result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress);
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
lzhDecoderSpec->SetDictionary(item.GetNumDictBits());
|
||||
result = lzhDecoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
||||
}
|
||||
/*
|
||||
else if (itemInfo.IsLh1GroupMethod())
|
||||
else if (item.IsLh1GroupMethod())
|
||||
{
|
||||
if(!lzh1Decoder)
|
||||
{
|
||||
lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder;
|
||||
lzh1Decoder = lzh1DecoderSpec;
|
||||
}
|
||||
try
|
||||
{
|
||||
lzh1DecoderSpec->SetDictionary(itemInfo.GetNumDictBits());
|
||||
result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, compressProgress);
|
||||
if (result == S_FALSE)
|
||||
throw "data error";
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
outStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
lzh1DecoderSpec->SetDictionary(item.GetNumDictBits());
|
||||
result = lzh1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
|
||||
bool crcOK = (outStreamSpec->GetCRC() == itemInfo.CRC);
|
||||
if (opRes == NExtract::NOperationResult::kOK)
|
||||
{
|
||||
if (result == S_FALSE)
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
{
|
||||
RINOK(result);
|
||||
if (outStreamSpec->GetCRC() != item.CRC)
|
||||
opRes = NExtract::NOperationResult::kCRCError;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
if(crcOK)
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
|
||||
else
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
|
||||
RINOK(extractCallback->SetOperationResult(opRes));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
@@ -31,7 +31,7 @@ static const wchar_t *kMethods[] =
|
||||
|
||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -42,43 +42,44 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidSolid, VT_BOOL}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidSolid, VT_BOOL}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidMethod:
|
||||
{
|
||||
UInt32 dict = 1;
|
||||
bool filter = false;
|
||||
for (int i = 0; i < _archive.Items.Size(); i++)
|
||||
{
|
||||
const CItem &item = _archive.Items[i];
|
||||
filter |= item.UseFilter;
|
||||
if (item.DictionarySize > dict)
|
||||
dict = item.DictionarySize;
|
||||
}
|
||||
prop = GetMethod(filter, dict);
|
||||
break;
|
||||
}
|
||||
case kpidSolid: prop = _archive.IsSolid; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(
|
||||
IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
@@ -142,6 +143,24 @@ static UString GetStringForSizeValue(UInt32 value)
|
||||
return result;
|
||||
}
|
||||
|
||||
UString CHandler::GetMethod(bool useItemFilter, UInt32 dictionary) const
|
||||
{
|
||||
NMethodType::EEnum methodIndex = _archive.Method;
|
||||
UString method;
|
||||
if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter)
|
||||
{
|
||||
method += kBcjMethod;
|
||||
method += L" ";
|
||||
}
|
||||
method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
||||
if (methodIndex == NMethodType::kLZMA)
|
||||
{
|
||||
method += L":";
|
||||
method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary);
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
bool CHandler::GetUncompressedSize(int index, UInt32 &size)
|
||||
{
|
||||
size = 0;
|
||||
@@ -185,24 +204,24 @@ bool CHandler::GetCompressedSize(int index, UInt32 &size)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
#ifdef NSIS_SCRIPT
|
||||
if (index >= (UInt32)_archive.Items.Size())
|
||||
{
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = L"[NSIS].nsi";
|
||||
prop = L"[NSIS].nsi";
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
propVariant = (UInt64)_archive.Script.Length();
|
||||
prop = (UInt64)_archive.Script.Length();
|
||||
break;
|
||||
case kpidSolid:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -215,57 +234,44 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
case kpidPath:
|
||||
{
|
||||
const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP));
|
||||
propVariant = (const wchar_t *)s;
|
||||
prop = (const wchar_t *)s;
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
{
|
||||
UInt32 size;
|
||||
if (GetUncompressedSize(index, size))
|
||||
propVariant = (UInt64)size;
|
||||
prop = (UInt64)size;
|
||||
break;
|
||||
}
|
||||
case kpidPackedSize:
|
||||
{
|
||||
UInt32 size;
|
||||
if (GetCompressedSize(index, size))
|
||||
propVariant = (UInt64)size;
|
||||
prop = (UInt64)size;
|
||||
break;
|
||||
}
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
if (item.DateTime.dwHighDateTime > 0x01000000 &&
|
||||
item.DateTime.dwHighDateTime < 0xFF000000)
|
||||
propVariant = item.DateTime;
|
||||
prop = item.DateTime;
|
||||
break;
|
||||
}
|
||||
case kpidMethod:
|
||||
{
|
||||
NMethodType::EEnum methodIndex = _archive.Method;
|
||||
UString method;
|
||||
if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && item.UseFilter)
|
||||
{
|
||||
method += kBcjMethod;
|
||||
method += L" ";
|
||||
}
|
||||
method += (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
||||
if (methodIndex == NMethodType::kLZMA)
|
||||
{
|
||||
method += L":";
|
||||
method += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: item.DictionarySize);
|
||||
}
|
||||
propVariant = method;
|
||||
prop = GetMethod(item.UseFilter, item.DictionarySize);
|
||||
break;
|
||||
}
|
||||
case kpidSolid:
|
||||
propVariant = _archive.IsSolid;
|
||||
prop = _archive.IsSolid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -478,8 +484,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!testMode)
|
||||
realOutStream.Release();
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(dataError ?
|
||||
NArchive::NExtract::NOperationResult::kDataError :
|
||||
NArchive::NExtract::NOperationResult::kOK));
|
||||
|
||||
@@ -26,6 +26,7 @@ class CHandler:
|
||||
bool GetUncompressedSize(int index, UInt32 &size);
|
||||
bool GetCompressedSize(int index, UInt32 &size);
|
||||
|
||||
UString GetMethod(bool useItemFilter, UInt32 dictionary) const;
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
QUERY_ENTRY_ISetCompressCodecsInfo
|
||||
|
||||
@@ -905,10 +905,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
|
||||
{
|
||||
Items.Sort(CompareItems, 0);
|
||||
int i;
|
||||
if (IsSolid)
|
||||
// if (IsSolid)
|
||||
for (i = 0; i + 1 < Items.Size();)
|
||||
{
|
||||
if (Items[i].Pos == Items[i + 1].Pos)
|
||||
if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || Items[i].Name == Items[i + 1].Name))
|
||||
Items.Delete(i + 1);
|
||||
else
|
||||
i++;
|
||||
|
||||
@@ -25,49 +25,14 @@ using namespace NWindows;
|
||||
namespace NArchive {
|
||||
namespace NRpm {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
// { NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
@@ -106,27 +71,16 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
/*
|
||||
case kpidPath:
|
||||
propVariant = (const wchar_t *)L"a.cpio.gz";
|
||||
break;
|
||||
*/
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
propVariant = m_Size;
|
||||
prop = m_Size;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
@@ -149,8 +103,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetTotal(m_Size));
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = 0;
|
||||
|
||||
@@ -171,23 +125,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
try
|
||||
{
|
||||
RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
return S_OK;
|
||||
}
|
||||
RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
return S_OK;
|
||||
return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -42,12 +42,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
static const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
enum // PropID
|
||||
{
|
||||
kpidUnPackVersion = kpidUserDefined
|
||||
};
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -58,7 +53,6 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidLastAccessTime, VT_FILETIME},
|
||||
{ NULL, kpidAttributes, VT_UI4},
|
||||
|
||||
|
||||
{ NULL, kpidEncrypted, VT_BOOL},
|
||||
{ NULL, kpidSolid, VT_BOOL},
|
||||
{ NULL, kpidCommented, VT_BOOL},
|
||||
@@ -66,17 +60,23 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidSplitAfter, VT_BOOL},
|
||||
{ NULL, kpidCRC, VT_UI4},
|
||||
{ NULL, kpidHostOS, VT_BSTR},
|
||||
{ NULL, kpidMethod, VT_BSTR}
|
||||
// { NULL, kpidDictionarySize, VT_UI4},
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1}
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidUnpackVer, VT_UI1}
|
||||
};
|
||||
|
||||
STATPROPSTG kArchiveProperties[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidSolid, VT_BOOL},
|
||||
{ NULL, kpidCommented, VT_BOOL},
|
||||
{ NULL, kpidNumBlocks, VT_UI4},
|
||||
{ NULL, kpidEncrypted, VT_BOOL},
|
||||
{ NULL, kpidIsVolume, VT_BOOL},
|
||||
{ NULL, kpidNumVolumes, VT_UI4},
|
||||
// { NULL, kpidCommented, VT_BOOL}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
UInt64 CHandler::GetPackSize(int refIndex) const
|
||||
{
|
||||
const CRefItem &refItem = _refItems[refIndex];
|
||||
@@ -88,56 +88,29 @@ UInt64 CHandler::GetPackSize(int refIndex) const
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
// COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidSolid:
|
||||
propVariant = _archiveInfo.IsSolid();
|
||||
break;
|
||||
case kpidCommented:
|
||||
propVariant = _archiveInfo.IsCommented();
|
||||
case kpidSolid: prop = _archiveInfo.IsSolid(); break;
|
||||
case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break;
|
||||
case kpidIsVolume: prop = _archiveInfo.IsVolume(); break;
|
||||
case kpidNumBlocks:
|
||||
{
|
||||
UInt32 numBlocks = 0;
|
||||
for (int i = 0; i < _refItems.Size(); i++)
|
||||
if (!IsSolid(i))
|
||||
numBlocks++;
|
||||
prop = (UInt32)numBlocks;
|
||||
break;
|
||||
}
|
||||
case kpidNumVolumes: prop = (UInt32)(_archives.Size() - 1);
|
||||
|
||||
// case kpidCommented: prop = _archiveInfo.IsCommented(); break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kArchiveProperties) / sizeof(kArchiveProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kArchiveProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
@@ -160,10 +133,23 @@ static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RarTimeToProp(const CRarTime &rarTime, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (RarTimeToFileTime(rarTime, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
prop = utcFileTime;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CRefItem &refItem = _refItems[index];
|
||||
const CItemEx &item = _items[refItem.ItemIndex];
|
||||
switch(propID)
|
||||
@@ -175,102 +161,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
u = item.UnicodeName;
|
||||
else
|
||||
u = MultiByteToUnicodeString(item.Name, CP_OEMCP);
|
||||
propVariant = (const wchar_t *)NItemName::WinNameToOSName(u);
|
||||
prop = (const wchar_t *)NItemName::WinNameToOSName(u);
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.UnPackSize;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
{
|
||||
propVariant = GetPackSize(index);
|
||||
break;
|
||||
}
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (RarTimeToFileTime(item.LastWriteTime, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidCreationTime:
|
||||
{
|
||||
if (item.IsCreationTimeDefined)
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (RarTimeToFileTime(item.CreationTime, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidLastAccessTime:
|
||||
{
|
||||
if (item.IsLastAccessTimeDefined)
|
||||
{
|
||||
FILETIME localFileTime, utcFileTime;
|
||||
if (RarTimeToFileTime(item.LastAccessTime, localFileTime))
|
||||
{
|
||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = item.GetWinAttributes();
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
propVariant = item.IsEncrypted();
|
||||
break;
|
||||
case kpidSolid:
|
||||
propVariant = IsSolid(index);
|
||||
break;
|
||||
case kpidCommented:
|
||||
propVariant = item.IsCommented();
|
||||
break;
|
||||
case kpidSplitBefore:
|
||||
propVariant = item.IsSplitBefore();
|
||||
break;
|
||||
case kpidSplitAfter:
|
||||
propVariant = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter();
|
||||
break;
|
||||
/*
|
||||
case kpidDictionarySize:
|
||||
if (!item.IsDirectory())
|
||||
propVariant = UInt32(0x10000 << item.GetDictSize());
|
||||
break;
|
||||
*/
|
||||
case kpidIsFolder: prop = item.IsDirectory(); break;
|
||||
case kpidSize: prop = item.UnPackSize; break;
|
||||
case kpidPackedSize: prop = GetPackSize(index); break;
|
||||
case kpidLastWriteTime: RarTimeToProp(item.LastWriteTime, prop);
|
||||
case kpidCreationTime: if (item.IsCreationTimeDefined) RarTimeToProp(item.CreationTime, prop); break;
|
||||
case kpidLastAccessTime: if (item.IsLastAccessTimeDefined) RarTimeToProp(item.LastAccessTime, prop); break;
|
||||
case kpidAttributes: prop = item.GetWinAttributes(); break;
|
||||
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
||||
case kpidSolid: prop = IsSolid(index); break;
|
||||
case kpidCommented: prop = item.IsCommented(); break;
|
||||
case kpidSplitBefore: prop = item.IsSplitBefore(); break;
|
||||
case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break;
|
||||
case kpidCRC:
|
||||
{
|
||||
const CItemEx &lastItem =
|
||||
_items[refItem.ItemIndex + refItem.NumItems - 1];
|
||||
if (lastItem.IsSplitAfter())
|
||||
propVariant = item.FileCRC;
|
||||
else
|
||||
propVariant = lastItem.FileCRC;
|
||||
const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
|
||||
prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);
|
||||
break;
|
||||
}
|
||||
case kpidUnPackVersion:
|
||||
propVariant = item.UnPackVersion;
|
||||
break;
|
||||
case kpidUnpackVer: prop = item.UnPackVersion; break;
|
||||
case kpidMethod:
|
||||
{
|
||||
UString method;
|
||||
@@ -293,15 +205,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
||||
ConvertUInt64ToString(item.Method, temp);
|
||||
method += temp;
|
||||
}
|
||||
propVariant = method;
|
||||
prop = method;
|
||||
break;
|
||||
}
|
||||
case kpidHostOS:
|
||||
propVariant = (item.HostOS < kNumHostOSes) ?
|
||||
(kHostOS[item.HostOS]) : kUnknownOS;
|
||||
break;
|
||||
case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -325,8 +234,12 @@ public:
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
UString ext = name.Mid(dotPos + 1);
|
||||
if (ext.CompareNoCase(L"RAR")==0 ||
|
||||
ext.CompareNoCase(L"EXE") == 0)
|
||||
if (ext.CompareNoCase(L"rar") == 0)
|
||||
{
|
||||
_afterPart = name.Mid(dotPos);
|
||||
basePart = name.Left(dotPos);
|
||||
}
|
||||
else if (ext.CompareNoCase(L"exe") == 0)
|
||||
{
|
||||
_afterPart = L".rar";
|
||||
basePart = name.Left(dotPos);
|
||||
@@ -338,11 +251,11 @@ public:
|
||||
_afterPart.Empty();
|
||||
_unchangedPart = basePart + UString(L".");
|
||||
_changedPart = L"r00";
|
||||
return true;;
|
||||
return true;
|
||||
}
|
||||
|
||||
int numLetters = 1;
|
||||
if (basePart.Right(numLetters) == L"1")
|
||||
if (basePart.Right(numLetters) == L"1" || basePart.Right(numLetters) == L"0")
|
||||
{
|
||||
while (numLetters < basePart.Length())
|
||||
{
|
||||
@@ -427,11 +340,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
break;
|
||||
UString baseName;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
break;
|
||||
baseName = propVariant.bstrVal;
|
||||
baseName = prop.bstrVal;
|
||||
}
|
||||
seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName());
|
||||
}
|
||||
@@ -572,8 +485,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
CObjectVector<CMethodItem> methodItems;
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = NULL;
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CFilterCoder *filterStreamSpec = new CFilterCoder;
|
||||
CMyComPtr<ISequentialInStream> filterStream = filterStreamSpec;
|
||||
@@ -586,18 +499,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
CFolderInStream *folderInStreamSpec = NULL;
|
||||
CMyComPtr<ISequentialInStream> folderInStream;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
bool solidStart = true;
|
||||
for(int i = 0; i < importantIndexes.Size(); i++,
|
||||
currentImportantTotalUnPacked += currentUnPackSize,
|
||||
currentImportantTotalPacked += currentPackSize)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(
|
||||
¤tImportantTotalUnPacked));
|
||||
lps->InSize = currentImportantTotalPacked;
|
||||
lps->OutSize = currentImportantTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
|
||||
Int32 askMode;
|
||||
if(extractStatuses[i])
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
else
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
@@ -648,9 +567,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
outStreamSpec->Init();
|
||||
realOutStream.Release();
|
||||
|
||||
UInt64 packedPos = currentImportantTotalPacked;
|
||||
UInt64 unpackedPos = currentImportantTotalUnPacked;
|
||||
|
||||
/*
|
||||
for (int partIndex = 0; partIndex < 1; partIndex++)
|
||||
{
|
||||
@@ -672,18 +588,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
folderInStreamSpec->Init(&_archives, &_items, refItem);
|
||||
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
&packedPos,
|
||||
&unpackedPos);
|
||||
|
||||
UInt64 packSize = currentPackSize;
|
||||
|
||||
// packedPos += item.PackSize;
|
||||
@@ -773,11 +677,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
{
|
||||
case '0':
|
||||
{
|
||||
if(copyCoderSpec == NULL)
|
||||
{
|
||||
copyCoderSpec = new NCompress::CCopyCoder;
|
||||
copyCoder = copyCoderSpec;
|
||||
}
|
||||
commonCoder = copyCoder;
|
||||
break;
|
||||
}
|
||||
@@ -850,8 +749,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
HRESULT result = commonCoder->Code(inStream, outStream,
|
||||
&packSize, &item.UnPackSize, compressProgress);
|
||||
HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.UnPackSize, progress);
|
||||
if (item.IsEncrypted())
|
||||
filterStreamSpec->ReleaseInStream();
|
||||
if (result == S_FALSE)
|
||||
|
||||
@@ -439,7 +439,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
|
||||
const UInt32 kSaltSize = 8;
|
||||
Byte salt[kSaltSize];
|
||||
if(!ReadBytesAndTestSize(salt, kSaltSize))
|
||||
return false;
|
||||
return S_FALSE;
|
||||
m_Position += kSaltSize;
|
||||
RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize))
|
||||
// Password
|
||||
|
||||
@@ -33,9 +33,9 @@ class CInArchiveInfo
|
||||
{
|
||||
public:
|
||||
UInt64 StartPosition;
|
||||
WORD Flags;
|
||||
UInt16 Flags;
|
||||
UInt64 CommentPosition;
|
||||
WORD CommentSize;
|
||||
UInt16 CommentSize;
|
||||
bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; }
|
||||
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
|
||||
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; }
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"Rar", L"rar", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, };
|
||||
{ L"Rar", L"rar r00", 0, 3, {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, 7, false, CreateArc, 0, };
|
||||
|
||||
REGISTER_ARC(Rar)
|
||||
|
||||
@@ -23,7 +23,7 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NSplit {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
// { NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -31,41 +31,8 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
class CSeqName
|
||||
{
|
||||
@@ -158,11 +125,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
return S_FALSE;
|
||||
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
return S_FALSE;
|
||||
_name = propVariant.bstrVal;
|
||||
_name = prop.bstrVal;
|
||||
}
|
||||
|
||||
int dotPos = _name.ReverseFind('.');
|
||||
@@ -219,11 +186,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
_totalSize = 0;
|
||||
UInt64 size;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
_totalSize += size;
|
||||
_sizes.Add(size);
|
||||
@@ -247,11 +214,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
if (!stream)
|
||||
break;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
_totalSize += size;
|
||||
_sizes.Add(size);
|
||||
@@ -288,25 +255,22 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = _subName;
|
||||
prop = _subName;
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
propVariant = _totalSize;
|
||||
prop = _totalSize;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
@@ -348,47 +312,28 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
return S_OK;
|
||||
}
|
||||
// currentItemSize = itemInfo.Size;
|
||||
|
||||
if(!testMode && (!realOutStream))
|
||||
{
|
||||
if (!testMode && (!realOutStream))
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
for(int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
// CMyComPtr<ISequentialInStream> inStream;
|
||||
// RINOK(volumeExtractCallback->GetInStream(_names[i], &inStream));
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalSize, ¤tTotalSize);
|
||||
for (int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
IInStream *inStream = _streams[i];
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
try
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, realOutStream,
|
||||
NULL, NULL, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
return S_OK;;
|
||||
}
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
currentItemSize = copyCoderSpec->TotalSize;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
return S_OK;
|
||||
return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -48,30 +48,30 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
if (newProperties != 0)
|
||||
{
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
}
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
else if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
if (propVariant.boolVal != VARIANT_FALSE)
|
||||
if (prop.boolVal != VARIANT_FALSE)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
}
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
else if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
if (propVariant.boolVal != VARIANT_FALSE)
|
||||
if (prop.boolVal != VARIANT_FALSE)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
@@ -80,11 +80,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
bool thereIsCopyData = false;
|
||||
if (newData != 0)
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
newSize = propVariant.uhVal.QuadPart;
|
||||
newSize = prop.uhVal.QuadPart;
|
||||
}
|
||||
else
|
||||
thereIsCopyData = true;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Tar/Handler.cpp
|
||||
/ Tar/Handler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
#include "../../Compress/Copy/CopyCoder.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
@@ -25,7 +26,7 @@ using namespace NTime;
|
||||
namespace NArchive {
|
||||
namespace NTar {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -36,41 +37,16 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidGroup, VT_BSTR},
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
@@ -81,7 +57,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
{
|
||||
CInArchive archive;
|
||||
|
||||
if(archive.Open(stream) != S_OK)
|
||||
if (archive.Open(stream) != S_OK)
|
||||
return S_FALSE;
|
||||
|
||||
_items.Clear();
|
||||
@@ -120,11 +96,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
|
||||
if (!openVolumeCallback)
|
||||
return S_FALSE;
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
return S_FALSE;
|
||||
UString baseName = propVariant.bstrVal;
|
||||
UString baseName = prop.bstrVal;
|
||||
baseName = baseName.Right(4);
|
||||
if (baseName.CompareNoCase(L".tar") != 0)
|
||||
return S_FALSE;
|
||||
@@ -157,45 +133,45 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
const NArchive::NTar::CItemEx &item = _items[index];
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = _items[index];
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = (const wchar_t *)NItemName::GetOSName2(
|
||||
prop = (const wchar_t *)NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
propVariant = (UInt64)item.Size;
|
||||
prop = (UInt64)item.Size;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
FILETIME utcFileTime;
|
||||
if (item.ModificationTime != 0)
|
||||
NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime);
|
||||
NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
|
||||
else
|
||||
{
|
||||
utcFileTime.dwLowDateTime = 0;
|
||||
utcFileTime.dwHighDateTime = 0;
|
||||
}
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidUser:
|
||||
propVariant = (const wchar_t *)
|
||||
prop = (const wchar_t *)
|
||||
MultiByteToUnicodeString(item.UserName, CP_OEMCP);
|
||||
break;
|
||||
case kpidGroup:
|
||||
propVariant = (const wchar_t *)
|
||||
prop = (const wchar_t *)
|
||||
MultiByteToUnicodeString(item.GroupName, CP_OEMCP);
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -208,86 +184,61 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
UInt64 totalSize = 0;
|
||||
if(numItems == 0)
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for(i = 0; i < numItems; i++)
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += _items[allFilesMode ? i : indices[i]].Size;
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize;
|
||||
|
||||
CMyComPtr<ICompressCoder> copyCoder;
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
lps->InSize = lps->OutSize = currentTotalSize;
|
||||
RINOK(lps->SetCur());
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 index = allFilesMode ? i : indices[i];
|
||||
const CItemEx &item = _items[index];
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
currentItemSize = item.Size;
|
||||
|
||||
if(item.IsDirectory())
|
||||
if (item.IsDirectory())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
if(!testMode && (!realOutStream))
|
||||
if (!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
{
|
||||
if (testMode)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||
streamSpec->SetStream(_inStream);
|
||||
streamSpec->Init(item.Size);
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec =
|
||||
new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
localCompressProgressSpec->Init(progress,
|
||||
¤tTotalSize, ¤tTotalSize);
|
||||
|
||||
if(!copyCoder)
|
||||
{
|
||||
copyCoder = new NCompress::CCopyCoder;
|
||||
}
|
||||
try
|
||||
{
|
||||
RINOK(copyCoder->Code(inStream, realOutStream,
|
||||
NULL, NULL, compressProgress));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
}
|
||||
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
streamSpec->Init(item.Size);
|
||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||
NArchive::NExtract::NOperationResult::kOK:
|
||||
NArchive::NExtract::NOperationResult::kDataError));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
|
||||
@@ -53,42 +53,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
bool isDirectoryStatusDefined;
|
||||
UInt32 attributes;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidAttributes, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
attributes = 0;
|
||||
else if (propVariant.vt != VT_UI4)
|
||||
else if (prop.vt != VT_UI4)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
attributes = propVariant.ulVal;
|
||||
attributes = prop.ulVal;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
|
||||
if (propVariant.vt != VT_FILETIME)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &prop));
|
||||
if (prop.vt != VT_FILETIME)
|
||||
return E_INVALIDARG;
|
||||
utcTime = propVariant.filetime;
|
||||
utcTime = prop.filetime;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
name.Empty();
|
||||
else if (propVariant.vt != VT_BSTR)
|
||||
else if (prop.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
name = propVariant.bstrVal;
|
||||
name = prop.bstrVal;
|
||||
}
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
|
||||
if (propVariant.vt == VT_EMPTY)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &prop));
|
||||
if (prop.vt == VT_EMPTY)
|
||||
isDirectoryStatusDefined = false;
|
||||
else if (propVariant.vt != VT_BOOL)
|
||||
else if (prop.vt != VT_BOOL)
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
{
|
||||
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
|
||||
updateItem.IsDirectory = (prop.boolVal != VARIANT_FALSE);
|
||||
isDirectoryStatusDefined = true;
|
||||
}
|
||||
}
|
||||
@@ -109,11 +109,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
{
|
||||
UInt64 size;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
|
||||
if (propVariant.vt != VT_UI8)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
size = propVariant.uhVal.QuadPart;
|
||||
size = prop.uhVal.QuadPart;
|
||||
}
|
||||
updateItem.Size = size;
|
||||
}
|
||||
|
||||
@@ -13,23 +13,9 @@
|
||||
#include "TarOut.h"
|
||||
#include "TarUpdate.h"
|
||||
|
||||
static const UInt64 kOneItemComplexity = 512;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NTar {
|
||||
|
||||
static HRESULT CopyBlock(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, ICompressProgressInfo *progress,
|
||||
UInt64 *totalSize = NULL)
|
||||
{
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
HRESULT result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||
if (totalSize != NULL)
|
||||
*totalSize = copyCoderSpec->TotalSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
|
||||
const CObjectVector<CUpdateItemInfo> &updateItems,
|
||||
@@ -48,25 +34,27 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
complexity += updateItem.Size;
|
||||
else
|
||||
complexity += inputItems[updateItem.IndexInArchive].GetFullSize();
|
||||
complexity += kOneItemComplexity;
|
||||
}
|
||||
|
||||
RINOK(updateCallback->SetTotal(complexity));
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(updateCallback, true);
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
streamSpec->SetStream(inStream);
|
||||
|
||||
complexity = 0;
|
||||
|
||||
for(i = 0; i < updateItems.Size(); i++)
|
||||
{
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
lps->InSize = lps->OutSize = complexity;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
const CUpdateItemInfo &updateItem = updateItems[i];
|
||||
CItem item;
|
||||
@@ -76,13 +64,13 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
item.Name = (updateItem.Name);
|
||||
if (updateItem.IsDirectory)
|
||||
{
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
|
||||
item.Size = 0;
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
|
||||
item.Size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
|
||||
item.Size = updateItem.Size;
|
||||
item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
|
||||
item.Size = updateItem.Size;
|
||||
}
|
||||
item.ModificationTime = updateItem.Time;
|
||||
item.DeviceMajorDefined = false;
|
||||
@@ -118,45 +106,40 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
RINOK(outArchive.WriteHeader(item));
|
||||
if (!updateItem.IsDirectory)
|
||||
{
|
||||
UInt64 totalSize;
|
||||
RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize));
|
||||
if (totalSize != item.Size)
|
||||
RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize != item.Size)
|
||||
return E_FAIL;
|
||||
RINOK(outArchive.FillDataResidual(item.Size));
|
||||
}
|
||||
}
|
||||
complexity += updateItem.Size;
|
||||
RINOK(updateCallback->SetOperationResult(
|
||||
NArchive::NUpdate::NOperationResult::kOK));
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
}
|
||||
else
|
||||
{
|
||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
|
||||
const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
|
||||
UInt64 size;
|
||||
if (updateItem.NewProperties)
|
||||
{
|
||||
RINOK(outArchive.WriteHeader(item));
|
||||
RINOK(inStream->Seek(existItemInfo.GetDataPosition(),
|
||||
STREAM_SEEK_SET, NULL));
|
||||
streamSpec->SetStream(inStream);
|
||||
streamSpec->Init(existItemInfo.Size);
|
||||
RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
size = existItemInfo.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(inStream->Seek(existItemInfo.HeaderPosition,
|
||||
STREAM_SEEK_SET, NULL));
|
||||
streamSpec->SetStream(inStream);
|
||||
streamSpec->Init(existItemInfo.GetFullSize());
|
||||
RINOK(inStream->Seek(existItemInfo.HeaderPosition, STREAM_SEEK_SET, NULL));
|
||||
size = existItemInfo.GetFullSize();
|
||||
}
|
||||
RINOK(CopyBlock(inStreamLimited, outStream, compressProgress));
|
||||
streamSpec->Init(size);
|
||||
|
||||
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
|
||||
if (copyCoderSpec->TotalSize != size)
|
||||
return E_FAIL;
|
||||
RINOK(outArchive.FillDataResidual(existItemInfo.Size));
|
||||
complexity += existItemInfo.GetFullSize();
|
||||
complexity += size;
|
||||
}
|
||||
complexity += kOneItemComplexity;
|
||||
}
|
||||
return outArchive.WriteFinishHeader();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -20,18 +20,7 @@ namespace NWim {
|
||||
|
||||
#define WIM_DETAILS
|
||||
|
||||
#ifdef WIM_DETAILS
|
||||
|
||||
enum
|
||||
{
|
||||
kpidVolume = kpidUserDefined,
|
||||
kpidOffset,
|
||||
kpidLinks
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -44,59 +33,63 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidLastWriteTime, VT_FILETIME}
|
||||
|
||||
#ifdef WIM_DETAILS
|
||||
, { L"Volume", kpidVolume, VT_UI4}
|
||||
, { L"Offset", kpidOffset, VT_UI8}
|
||||
, { L"Links", kpidLinks, VT_UI4}
|
||||
, { NULL, kpidVolume, VT_UI4}
|
||||
, { NULL, kpidOffset, VT_UI8}
|
||||
, { NULL, kpidLinks, VT_UI4}
|
||||
#endif
|
||||
};
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
{ NULL, kpidIsVolume, VT_BOOL},
|
||||
{ NULL, kpidVolume, VT_UI4},
|
||||
{ NULL, kpidNumVolumes, VT_UI4}
|
||||
};
|
||||
|
||||
static const wchar_t *kStreamsNamePrefix = L"Files" WSTRING_PATH_SEPARATOR;
|
||||
static const wchar_t *kMethodLZX = L"LZX";
|
||||
static const wchar_t *kMethodCopy = L"Copy";
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidSize: prop = m_Database.GetUnpackSize(); break;
|
||||
case kpidPackedSize: prop = m_Database.GetPackSize(); break;
|
||||
case kpidIsVolume:
|
||||
if (m_Xmls.Size() > 0)
|
||||
{
|
||||
UInt16 volIndex = m_Xmls[0].VolIndex;
|
||||
if (volIndex < m_Volumes.Size())
|
||||
prop = (m_Volumes[volIndex].Header.NumParts > 1);
|
||||
}
|
||||
break;
|
||||
case kpidVolume:
|
||||
if (m_Xmls.Size() > 0)
|
||||
{
|
||||
UInt16 volIndex = m_Xmls[0].VolIndex;
|
||||
if (volIndex < m_Volumes.Size())
|
||||
prop = m_Volumes[volIndex].Header.PartNumber;
|
||||
}
|
||||
break;
|
||||
case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1);
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
if (srcItem.lpwstrName == 0)
|
||||
*name = 0;
|
||||
else
|
||||
*name = ::SysAllocString(srcItem.lpwstrName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
if (index < (UInt32)m_Database.Items.Size())
|
||||
{
|
||||
const CItem &item = m_Database.Items[index];
|
||||
@@ -108,7 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
{
|
||||
case kpidPath:
|
||||
if (item.HasMetadata)
|
||||
propVariant = item.Name;
|
||||
prop = item.Name;
|
||||
else
|
||||
{
|
||||
wchar_t sz[32];
|
||||
@@ -117,62 +110,62 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
while (s.Length() < m_NameLenForStreams)
|
||||
s = L'0' + s;
|
||||
s = UString(kStreamsNamePrefix) + s;
|
||||
propVariant = s;
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidAttributes:
|
||||
if (item.HasMetadata)
|
||||
propVariant = item.Attributes;
|
||||
prop = item.Attributes;
|
||||
break;
|
||||
case kpidCreationTime:
|
||||
if (item.HasMetadata)
|
||||
propVariant = item.CreationTime;
|
||||
prop = item.CreationTime;
|
||||
break;
|
||||
case kpidLastAccessTime:
|
||||
if (item.HasMetadata)
|
||||
propVariant = item.LastAccessTime;
|
||||
prop = item.LastAccessTime;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
if (item.HasMetadata)
|
||||
propVariant = item.LastWriteTime;
|
||||
prop = item.LastWriteTime;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
if (si)
|
||||
propVariant = si->Resource.PackSize;
|
||||
prop = si->Resource.PackSize;
|
||||
else
|
||||
propVariant = (UInt64)0;
|
||||
prop = (UInt64)0;
|
||||
break;
|
||||
case kpidSize:
|
||||
if (si)
|
||||
propVariant = si->Resource.UnpackSize;
|
||||
prop = si->Resource.UnpackSize;
|
||||
else
|
||||
propVariant = (UInt64)0;
|
||||
prop = (UInt64)0;
|
||||
break;
|
||||
case kpidMethod:
|
||||
if (si)
|
||||
if (si->Resource.IsCompressed())
|
||||
propVariant = kMethodLZX;
|
||||
prop = kMethodLZX;
|
||||
else
|
||||
propVariant = kMethodCopy;
|
||||
prop = kMethodCopy;
|
||||
break;
|
||||
#ifdef WIM_DETAILS
|
||||
case kpidVolume:
|
||||
if (si)
|
||||
propVariant = (UInt32)si->PartNumber;
|
||||
prop = (UInt32)si->PartNumber;
|
||||
break;
|
||||
case kpidOffset:
|
||||
if (si)
|
||||
propVariant = (UInt64)si->Resource.Offset;
|
||||
prop = (UInt64)si->Resource.Offset;
|
||||
break;
|
||||
case kpidLinks:
|
||||
if (si)
|
||||
propVariant = (UInt32)si->RefCount;
|
||||
prop = (UInt32)si->RefCount;
|
||||
else
|
||||
propVariant = (UInt64)0;
|
||||
prop = (UInt64)0;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@@ -188,23 +181,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
wchar_t sz[32];
|
||||
ConvertUInt64ToString(m_Xmls[index].VolIndex, sz);
|
||||
UString s = (UString)sz + L".xml";
|
||||
propVariant = s;
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
prop = false;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
case kpidSize:
|
||||
propVariant = (UInt64)m_Xmls[index].Data.GetCapacity();
|
||||
prop = (UInt64)m_Xmls[index].Data.GetCapacity();
|
||||
break;
|
||||
case kpidMethod:
|
||||
propVariant = L"Copy";
|
||||
prop = L"Copy";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -317,11 +310,11 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
break;
|
||||
numVolumes = header.NumParts;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
|
||||
if (propVariant.vt != VT_BSTR)
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
||||
if (prop.vt != VT_BSTR)
|
||||
break;
|
||||
seqName.InitName(propVariant.bstrVal);
|
||||
seqName.InitName(prop.bstrVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -381,29 +374,33 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
RINOK(extractCallback->SetTotal(totalSize));
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
UInt64 currentItemSize = 0;
|
||||
UInt64 currentTotalPacked = 0;
|
||||
UInt64 currentTotalUnPacked = 0;
|
||||
UInt64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
int prevSuccessStreamIndex = -1;
|
||||
|
||||
CUnpacker unpacker;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
|
||||
for (i = 0; i < numItems; currentTotalSize += currentItemSize)
|
||||
for (i = 0; i < numItems; currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
{
|
||||
currentItemSize = 0;
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
|
||||
RINOK(lps->SetCur());
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
i++;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
@@ -413,13 +410,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
const CByteBuffer &data = m_Xmls[index - (UInt32)m_Database.Items.Size()].Data;
|
||||
currentItemSize = data.GetCapacity();
|
||||
currentItemUnPacked = data.GetCapacity();
|
||||
if (realOutStream)
|
||||
{
|
||||
RINOK(WriteStream(realOutStream, (const Byte *)data, (UInt32)data.GetCapacity(), NULL));
|
||||
realOutStream.Release();
|
||||
}
|
||||
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -432,32 +429,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(item.HasStream() ?
|
||||
NArchive::NExtract::NOperationResult::kDataError :
|
||||
NArchive::NExtract::NOperationResult::kOK));
|
||||
NExtract::NOperationResult::kDataError :
|
||||
NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
const CStreamInfo &si = m_Database.Streams[streamIndex];
|
||||
currentItemSize = si.Resource.UnpackSize;
|
||||
currentItemUnPacked = si.Resource.UnpackSize;
|
||||
currentItemPacked = si.Resource.PackSize;
|
||||
|
||||
if(!testMode && (!realOutStream))
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
if (streamIndex != prevSuccessStreamIndex || realOutStream)
|
||||
{
|
||||
Byte digest[20];
|
||||
localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize);
|
||||
HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, compressProgress, digest);
|
||||
HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, progress, digest);
|
||||
if (res == S_OK)
|
||||
{
|
||||
if (memcmp(digest, si.Hash, kHashSize) == 0)
|
||||
prevSuccessStreamIndex = streamIndex;
|
||||
else
|
||||
opRes = NArchive::NExtract::NOperationResult::kCRCError;
|
||||
opRes = NExtract::NOperationResult::kCRCError;
|
||||
}
|
||||
else if (res == S_FALSE)
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
opRes = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -107,6 +107,23 @@ struct CDatabase
|
||||
{
|
||||
CRecordVector<CStreamInfo> Streams;
|
||||
CObjectVector<CItem> Items;
|
||||
|
||||
UInt64 GetUnpackSize() const
|
||||
{
|
||||
UInt64 res = 0;
|
||||
for (int i = 0; i < Streams.Size(); i++)
|
||||
res += Streams[i].Resource.UnpackSize;
|
||||
return res;
|
||||
}
|
||||
|
||||
UInt64 GetPackSize() const
|
||||
{
|
||||
UInt64 res = 0;
|
||||
for (int i = 0; i < Streams.Size(); i++)
|
||||
res += Streams[i].Resource.PackSize;
|
||||
return res;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Streams.Clear();
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/MyInitGuid.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "ZHandler.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
// {23170F69-40C1-278A-1000-000110050000}
|
||||
DEFINE_GUID(CLSID_CZHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /* lpReserved */)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STDAPI CreateObject(
|
||||
const GUID *classID,
|
||||
const GUID *interfaceID,
|
||||
void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*classID != CLSID_CZHandler)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
int needIn = *interfaceID == IID_IInArchive;
|
||||
int needOut = *interfaceID == IID_IOutArchive;
|
||||
if (needIn || needOut)
|
||||
{
|
||||
NArchive::NZ::CHandler *temp = new NArchive::NZ::CHandler;
|
||||
if (needIn)
|
||||
{
|
||||
CMyComPtr<IInArchive> inArchive = (IInArchive *)temp;
|
||||
*outObject = inArchive.Detach();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMyComPtr<IOutArchive> outArchive = (IOutArchive *)temp;
|
||||
*outObject = outArchive.Detach();
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
propVariant = L"Z";
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(
|
||||
(const char *)&CLSID_CZHandler, sizeof(GUID))) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
propVariant = L"z taz";
|
||||
break;
|
||||
case NArchive::kAddExtension:
|
||||
propVariant = L"* .tar";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = false;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = true;
|
||||
break;
|
||||
case NArchive::kStartSignature:
|
||||
{
|
||||
const unsigned char sig[] = { 0x1F, 0x9D };
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen((const char *)sig, 2)) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
@@ -19,47 +19,13 @@
|
||||
namespace NArchive {
|
||||
namespace NZ {
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidPackedSize, VT_UI8},
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
|
||||
{
|
||||
value->vt = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
@@ -67,24 +33,15 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
if (index != 0)
|
||||
return E_INVALIDARG;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidIsFolder:
|
||||
propVariant = false;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = _packSize;
|
||||
break;
|
||||
case kpidPackedSize: prop = _packSize; break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
static const int kSignatureSize = 3;
|
||||
@@ -151,26 +108,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
|
||||
if(!testMode && !realOutStream)
|
||||
if (!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
|
||||
extractCallback->PrepareOperation(askMode);
|
||||
|
||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->Init(realOutStream);
|
||||
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
outStreamSpec->Init();
|
||||
realOutStream.Release();
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
localProgressSpec->Init(extractCallback, true);
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL));
|
||||
|
||||
@@ -182,20 +139,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
int opResult;
|
||||
if (result != S_OK)
|
||||
opResult = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
opResult = NExtract::NOperationResult::kUnSupportedMethod;
|
||||
else
|
||||
{
|
||||
result = decoder->Code(_stream, outStream, NULL, NULL, progress);
|
||||
outStream.Release();
|
||||
if (result == S_FALSE)
|
||||
opResult = NArchive::NExtract::NOperationResult::kDataError;
|
||||
else if (result == S_OK)
|
||||
opResult = NArchive::NExtract::NOperationResult::kOK;
|
||||
opResult = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
return result;
|
||||
{
|
||||
RINOK(result);
|
||||
opResult = NExtract::NOperationResult::kOK;
|
||||
}
|
||||
}
|
||||
RINOK(extractCallback->SetOperationResult(opResult));
|
||||
return S_OK;
|
||||
outStream.Release();
|
||||
return extractCallback->SetOperationResult(opResult);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
@@ -74,15 +74,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
static const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidUnPackVersion,
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProperties[] =
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidIsFolder, VT_BOOL},
|
||||
@@ -99,7 +91,7 @@ STATPROPSTG kProperties[] =
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidHostOS, VT_BSTR}
|
||||
|
||||
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
|
||||
// { NULL, kpidUnpackVer, VT_UI1},
|
||||
};
|
||||
|
||||
const wchar_t *kMethods[] =
|
||||
@@ -147,7 +139,7 @@ CStrongCryptoPair g_StrongCryptoPairs[] =
|
||||
{ NStrongCryptoFlags::kRC4, L"RC4" }
|
||||
};
|
||||
|
||||
STATPROPSTG kArcProperties[] =
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidComment, VT_BSTR}
|
||||
};
|
||||
@@ -158,7 +150,7 @@ CHandler::CHandler():
|
||||
InitMethodProperties();
|
||||
}
|
||||
|
||||
static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &propVariant)
|
||||
static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
int size = (int)data.GetCapacity();
|
||||
if (size <= 0)
|
||||
@@ -168,62 +160,29 @@ static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM:
|
||||
memcpy(p, (const Byte *)data, size);
|
||||
p[size] = '\0';
|
||||
s.ReleaseBuffer();
|
||||
propVariant = MultiByteToUnicodeString(s, codePage);
|
||||
prop = MultiByteToUnicodeString(s, codePage);
|
||||
}
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidComment:
|
||||
{
|
||||
StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, propVariant);
|
||||
StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = sizeof(kArcProperties) / sizeof(kArcProperties[0]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
|
||||
BSTR * name, PROPID * propID, VARTYPE *varType)
|
||||
{
|
||||
if (index >= sizeof(kArcProperties) / sizeof(kArcProperties[0]))
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kArcProperties[index];
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = m_Items.Size();
|
||||
@@ -233,22 +192,22 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant propVariant;
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
const CItemEx &item = m_Items[index];
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
propVariant = NItemName::GetOSName2(
|
||||
prop = NItemName::GetOSName2(
|
||||
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
|
||||
break;
|
||||
case kpidIsFolder:
|
||||
propVariant = item.IsDirectory();
|
||||
prop = item.IsDirectory();
|
||||
break;
|
||||
case kpidSize:
|
||||
propVariant = item.UnPackSize;
|
||||
prop = item.UnPackSize;
|
||||
break;
|
||||
case kpidPackedSize:
|
||||
propVariant = item.PackSize;
|
||||
prop = item.PackSize;
|
||||
break;
|
||||
case kpidLastWriteTime:
|
||||
{
|
||||
@@ -260,23 +219,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
}
|
||||
else
|
||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
||||
propVariant = utcFileTime;
|
||||
prop = utcFileTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttributes:
|
||||
propVariant = item.GetWinAttributes();
|
||||
prop = item.GetWinAttributes();
|
||||
break;
|
||||
case kpidEncrypted:
|
||||
propVariant = item.IsEncrypted();
|
||||
prop = item.IsEncrypted();
|
||||
break;
|
||||
case kpidComment:
|
||||
{
|
||||
StringToProp(item.Comment, item.GetCodePage(), propVariant);
|
||||
StringToProp(item.Comment, item.GetCodePage(), prop);
|
||||
break;
|
||||
}
|
||||
case kpidCRC:
|
||||
if (item.IsThereCrc())
|
||||
propVariant = item.FileCRC;
|
||||
prop = item.FileCRC;
|
||||
break;
|
||||
case kpidMethod:
|
||||
{
|
||||
@@ -335,15 +294,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
ConvertUInt64ToString(methodId, s);
|
||||
method += s;
|
||||
}
|
||||
propVariant = method;
|
||||
prop = method;
|
||||
break;
|
||||
}
|
||||
case kpidHostOS:
|
||||
propVariant = (item.MadeByVersion.HostOS < kNumHostOSes) ?
|
||||
prop = (item.MadeByVersion.HostOS < kNumHostOSes) ?
|
||||
(kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS;
|
||||
break;
|
||||
}
|
||||
propVariant.Detach(value);
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
@@ -731,15 +690,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
totalUnPacked += item.UnPackSize;
|
||||
totalPacked += item.PackSize;
|
||||
}
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
RINOK(extractCallback->SetTotal(totalUnPacked));
|
||||
|
||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
||||
UInt64 currentItemUnPacked, currentItemPacked;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
|
||||
currentTotalPacked += currentItemPacked)
|
||||
@@ -747,7 +705,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
currentItemUnPacked = 0;
|
||||
currentItemPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalUnPacked));
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = currentTotalUnPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
@@ -792,14 +753,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
localProgressSpec->Init(extractCallback, false);
|
||||
localCompressProgressSpec->Init(progress, ¤tTotalPacked, ¤tTotalUnPacked);
|
||||
|
||||
Int32 res;
|
||||
RINOK(myDecoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
m_Archive, item, realOutStream, extractCallback,
|
||||
compressProgress, _numThreads, res));
|
||||
progress, _numThreads, res));
|
||||
realOutStream.Release();
|
||||
|
||||
RINOK(extractCallback->SetOperationResult(res))
|
||||
|
||||
@@ -542,6 +542,10 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
|
||||
// cdInfo.NumEntries = GetUInt16(buf + i + 10);
|
||||
cdInfo.Size = GetUInt32(buf + i + 12);
|
||||
cdInfo.Offset = GetUInt32(buf + i + 16);
|
||||
UInt64 curPos = endPosition - bufSize + i;
|
||||
UInt64 cdEnd = cdInfo.Size + cdInfo.Offset;
|
||||
if (curPos > cdEnd)
|
||||
m_ArchiveInfo.Base = curPos - cdEnd;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ public:
|
||||
if (CentralExtra.GetWzAesField(aesField))
|
||||
return aesField.NeedCrc();
|
||||
}
|
||||
return true;
|
||||
return (FileCRC != 0 || !IsDirectory());
|
||||
}
|
||||
|
||||
WORD GetCodePage() const
|
||||
|
||||
@@ -237,6 +237,87 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CMtProgressMixer2:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 ProgressOffset;
|
||||
UInt64 InSizes[2];
|
||||
UInt64 OutSizes[2];
|
||||
CMyComPtr<IProgress> Progress;
|
||||
CMyComPtr<ICompressProgressInfo> RatioProgress;
|
||||
bool _inSizeIsMain;
|
||||
public:
|
||||
NWindows::NSynchronization::CCriticalSection CriticalSection;
|
||||
MY_UNKNOWN_IMP
|
||||
void Create(IProgress *progress, bool inSizeIsMain);
|
||||
void SetProgressOffset(UInt64 progressOffset);
|
||||
HRESULT SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize);
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
void CMtProgressMixer2::Create(IProgress *progress, bool inSizeIsMain)
|
||||
{
|
||||
Progress = progress;
|
||||
Progress.QueryInterface(IID_ICompressProgressInfo, &RatioProgress);
|
||||
_inSizeIsMain = inSizeIsMain;
|
||||
ProgressOffset = InSizes[0] = InSizes[1] = OutSizes[0] = OutSizes[1] = 0;
|
||||
}
|
||||
|
||||
void CMtProgressMixer2::SetProgressOffset(UInt64 progressOffset)
|
||||
{
|
||||
CriticalSection.Enter();
|
||||
ProgressOffset = progressOffset;
|
||||
CriticalSection.Leave();
|
||||
}
|
||||
|
||||
HRESULT CMtProgressMixer2::SetRatioInfo(int index, const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
|
||||
if (index == 0 && RatioProgress)
|
||||
{
|
||||
RINOK(RatioProgress->SetRatioInfo(inSize, outSize));
|
||||
}
|
||||
if (inSize != 0)
|
||||
InSizes[index] = *inSize;
|
||||
if (outSize != 0)
|
||||
OutSizes[index] = *outSize;
|
||||
UInt64 v = ProgressOffset + (_inSizeIsMain ?
|
||||
(InSizes[0] + InSizes[1]) :
|
||||
(OutSizes[0] + OutSizes[1]));
|
||||
return Progress->SetCompleted(&v);
|
||||
}
|
||||
|
||||
STDMETHODIMP CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
return SetRatioInfo(0, inSize, outSize);
|
||||
}
|
||||
|
||||
class CMtProgressMixer:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
CMtProgressMixer2 *Mixer2;
|
||||
CMyComPtr<ICompressProgressInfo> RatioProgress;
|
||||
void Create(IProgress *progress, bool inSizeIsMain);
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
void CMtProgressMixer::Create(IProgress *progress, bool inSizeIsMain)
|
||||
{
|
||||
Mixer2 = new CMtProgressMixer2;
|
||||
RatioProgress = Mixer2;
|
||||
Mixer2->Create(progress, inSizeIsMain);
|
||||
}
|
||||
|
||||
STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
return Mixer2->SetRatioInfo(1, inSize, outSize);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -301,21 +382,20 @@ static HRESULT Update2St(
|
||||
const CByteBuffer &comment,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
{
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
|
||||
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
|
||||
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(updateCallback, true);
|
||||
|
||||
CAddCommon compressor(*options);
|
||||
|
||||
CObjectVector<CItem> items;
|
||||
UInt64 complexity = 0;
|
||||
UInt64 unpackSizeTotal = 0, packSizeTotal = 0;
|
||||
|
||||
for (int itemIndex = 0; itemIndex < updateItems.Size(); itemIndex++)
|
||||
{
|
||||
RINOK(updateCallback->SetCompleted(&complexity));
|
||||
lps->InSize = unpackSizeTotal;
|
||||
lps->OutSize = packSizeTotal;
|
||||
RINOK(lps->SetCur());
|
||||
const CUpdateItem &updateItem = updateItems[itemIndex];
|
||||
CItemEx item;
|
||||
if (!updateItem.NewProperties || !updateItem.NewData)
|
||||
@@ -338,7 +418,7 @@ static HRESULT Update2St(
|
||||
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
|
||||
if (res == S_FALSE)
|
||||
{
|
||||
complexity += updateItem.Size + NFileHeader::kLocalBlockSize;
|
||||
lps->ProgressOffset += updateItem.Size;
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
@@ -350,23 +430,26 @@ static HRESULT Update2St(
|
||||
CCompressingResult compressingResult;
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
archive.CreateStreamForCompressing(&outStream);
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
RINOK(compressor.Compress(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
fileInStream, outStream, compressProgress, compressingResult));
|
||||
fileInStream, outStream, progress, compressingResult));
|
||||
SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
complexity += item.UnPackSize;
|
||||
unpackSizeTotal += item.UnPackSize;
|
||||
packSizeTotal += item.PackSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, compressProgress, complexity));
|
||||
UInt64 complexity = 0;
|
||||
lps->SendRatio = false;
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
|
||||
lps->SendRatio = true;
|
||||
lps->ProgressOffset += complexity;
|
||||
}
|
||||
items.Add(item);
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
lps->ProgressOffset += NFileHeader::kLocalBlockSize;
|
||||
}
|
||||
archive.WriteCentralDir(items, comment);
|
||||
return S_OK;
|
||||
@@ -477,17 +560,12 @@ static HRESULT Update2(
|
||||
|
||||
CObjectVector<CItem> items;
|
||||
|
||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||
localProgressSpec->Init(updateCallback, true);
|
||||
CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer;
|
||||
CMyComPtr<ICompressProgressInfo> progress = mtProgressMixerSpec;
|
||||
mtProgressMixerSpec->Create(updateCallback, true);
|
||||
|
||||
CMtCompressProgressMixer mtCompressProgressMixer;
|
||||
mtCompressProgressMixer.Init(numThreads + 1, localProgress);
|
||||
|
||||
// we need one item for main stream
|
||||
CMtCompressProgress *progressMainSpec = new CMtCompressProgress();
|
||||
CMyComPtr<ICompressProgressInfo> progressMain = progressMainSpec;
|
||||
progressMainSpec->Init(&mtCompressProgressMixer, (int)numThreads);
|
||||
mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress);
|
||||
|
||||
CMemBlockManagerMt memManager(kBlockSize);
|
||||
CMemRefs refs(&memManager);
|
||||
@@ -551,12 +629,13 @@ static HRESULT Update2(
|
||||
}
|
||||
CMyComPtr<ISequentialInStream> fileInStream;
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(mtCompressProgressMixer.CriticalSection);
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection);
|
||||
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
|
||||
if (res == S_FALSE)
|
||||
{
|
||||
complexity += updateItem.Size;
|
||||
complexity++;
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
refs.Refs[mtItemIndex - 1].Skip = true;
|
||||
continue;
|
||||
@@ -633,7 +712,6 @@ static HRESULT Update2(
|
||||
options->IsAesMode, options->AesKeyMode, item);
|
||||
SetFileHeader(archive, *options, updateItem, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
complexity += item.UnPackSize;
|
||||
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
memRef.FreeOpt(&memManager);
|
||||
}
|
||||
@@ -667,7 +745,6 @@ static HRESULT Update2(
|
||||
options->IsAesMode, options->AesKeyMode, item);
|
||||
SetFileHeader(archive, *options, updateItem, item);
|
||||
archive.WriteLocalHeader(item);
|
||||
complexity += item.UnPackSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -682,11 +759,11 @@ static HRESULT Update2(
|
||||
}
|
||||
else
|
||||
{
|
||||
progressMainSpec->Reinit();
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progressMain, complexity));
|
||||
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
|
||||
}
|
||||
items.Add(item);
|
||||
complexity += NFileHeader::kLocalBlockSize;
|
||||
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
|
||||
itemIndex++;
|
||||
}
|
||||
archive.WriteCentralDir(items, comment);
|
||||
|
||||
@@ -2411,12 +2411,20 @@ SOURCE=..\..\ICoder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IDecl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IPassword.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IProgress.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\IStream.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
|
||||
@@ -389,11 +389,12 @@ int Main2(
|
||||
eo.YesToAll = yesToAll;
|
||||
|
||||
UString errorMessage;
|
||||
CDecompressStat stat;
|
||||
HRESULT result = DecompressArchives(
|
||||
codecs,
|
||||
v1, v2,
|
||||
wildcardCensorHead,
|
||||
eo, &openCallback, ecs, errorMessage);
|
||||
eo, &openCallback, ecs, errorMessage, stat);
|
||||
if (!errorMessage.IsEmpty())
|
||||
{
|
||||
(*g_StdStream) << endl << "Error: " << errorMessage;;
|
||||
|
||||
@@ -240,7 +240,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResul
|
||||
}
|
||||
}
|
||||
if(_outFileStream != NULL)
|
||||
_outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
|
||||
_outFileStreamSpec->SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
|
||||
_outFileStream.Release();
|
||||
if (_extractMode)
|
||||
NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../../ICoder.h"
|
||||
|
||||
#ifndef _NO_PROGRESS
|
||||
#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h"
|
||||
#include "../../UI/FileManager/ProgressDialog.h"
|
||||
#endif
|
||||
|
||||
class CExtractCallbackImp:
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../../UI/Common/OpenArchive.h"
|
||||
|
||||
#include "../../UI/Explorer/MyMessages.h"
|
||||
#include "../../FileManager/FormatUtils.h"
|
||||
#include "../../UI/FileManager/FormatUtils.h"
|
||||
|
||||
#include "ExtractCallback.h"
|
||||
|
||||
|
||||
@@ -668,20 +668,20 @@ SOURCE=..\..\UI\GUI\OpenCallbackGUI.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp
|
||||
SOURCE=..\..\UI\FileManager\ProgressDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h
|
||||
SOURCE=..\..\UI\FileManager\ProgressDialog.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\FormatUtils.cpp
|
||||
SOURCE=..\..\UI\FileManager\FormatUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\FormatUtils.h
|
||||
SOURCE=..\..\UI\FileManager\FormatUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "C"
|
||||
|
||||
@@ -64,6 +64,7 @@ UI_COMMON_OBJS = \
|
||||
|
||||
FM_OBJS = \
|
||||
$O\FormatUtils.obj \
|
||||
$O\ProgressDialog.obj \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O\CoderMixer2.obj \
|
||||
@@ -125,7 +126,6 @@ OBJS = \
|
||||
$(LZ_OBJS) \
|
||||
$(LZMA_OPT_OBJS) \
|
||||
$O\MyMessages.obj \
|
||||
$O\ProgressDialog.obj \
|
||||
$(C_OBJS) \
|
||||
$(C_BRANCH_OBJS) \
|
||||
$(CRC_OBJS) \
|
||||
@@ -149,7 +149,7 @@ $(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(FM_OBJS): ../../FileManager/$(*B).cpp
|
||||
$(FM_OBJS): ../../UI/FileManager//$(*B).cpp
|
||||
$(COMPL)
|
||||
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
@@ -167,8 +167,6 @@ $(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
|
||||
|
||||
$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
|
||||
$(COMPL)
|
||||
$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp
|
||||
$(COMPL)
|
||||
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O1)
|
||||
|
||||
@@ -13,4 +13,4 @@ BEGIN
|
||||
IDS_PROGRESS_EXTRACTING "Extracting"
|
||||
END
|
||||
|
||||
#include "../../FileManager/Resource/ProgressDialog/resource.rc"
|
||||
#include "../../UI/FileManager/ProgressDialog.rc"
|
||||
|
||||
@@ -389,35 +389,35 @@ SOURCE=..\..\Crypto\Hash\Sha256.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp
|
||||
SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h
|
||||
SOURCE=..\..\UI\FileManager\MessagesDialog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp
|
||||
SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h
|
||||
SOURCE=..\..\UI\FileManager\OverwriteDialog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp
|
||||
SOURCE=..\..\UI\FileManager\PasswordDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h
|
||||
SOURCE=..\..\UI\FileManager\PasswordDialog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp
|
||||
SOURCE=..\..\UI\FileManager\ProgressDialog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h
|
||||
SOURCE=..\..\UI\FileManager\ProgressDialog.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "7zip Common"
|
||||
@@ -533,19 +533,19 @@ SOURCE=..\..\Common\VirtThread.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\ExtractCallback.cpp
|
||||
SOURCE=..\..\UI\FileManager\ExtractCallback.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\ExtractCallback.h
|
||||
SOURCE=..\..\UI\FileManager\ExtractCallback.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\FormatUtils.cpp
|
||||
SOURCE=..\..\UI\FileManager\FormatUtils.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\FileManager\FormatUtils.h
|
||||
SOURCE=..\..\UI\FileManager\FormatUtils.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Windows"
|
||||
|
||||
@@ -68,6 +68,10 @@ UI_COMMON_OBJS = \
|
||||
FM_OBJS = \
|
||||
$O\ExtractCallback.obj \
|
||||
$O\FormatUtils.obj \
|
||||
$O\MessagesDialog.obj \
|
||||
$O\OverwriteDialog.obj \
|
||||
$O\PasswordDialog.obj \
|
||||
$O\ProgressDialog.obj \
|
||||
|
||||
AR_COMMON_OBJS = \
|
||||
$O\CoderMixer2.obj \
|
||||
@@ -150,10 +154,6 @@ OBJS = \
|
||||
$(7ZAES_OPT_OBJS) \
|
||||
$(AES_OPT_OBJS) \
|
||||
$O\MyMessages.obj \
|
||||
$O\MessagesDialog.obj \
|
||||
$O\OverwriteDialog.obj \
|
||||
$O\PasswordDialog.obj \
|
||||
$O\ProgressDialog.obj \
|
||||
$(C_OBJS) \
|
||||
$(C_BRANCH_OBJS) \
|
||||
$(CRC_OBJS) \
|
||||
@@ -178,7 +178,7 @@ $(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(FM_OBJS): ../../FileManager/$(*B).cpp
|
||||
$(FM_OBJS): ../../UI/FileManager/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
|
||||
$(COMPL)
|
||||
@@ -205,14 +205,6 @@ $(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
|
||||
|
||||
$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
|
||||
$(COMPL)
|
||||
$O\MessagesDialog.obj: ../../FileManager/Resource/MessagesDialog/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\OverwriteDialog.obj: ../../FileManager/Resource/OverwriteDialog./$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\PasswordDialog.obj: ../../FileManager/Resource/PasswordDialog/$(*B).cpp
|
||||
$(COMPL)
|
||||
$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp
|
||||
$(COMPL)
|
||||
$(C_OBJS): ../../../../C/$(*B).c
|
||||
$(COMPL_O1)
|
||||
$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
|
||||
|
||||
@@ -27,8 +27,8 @@ BEGIN
|
||||
PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
|
||||
END
|
||||
|
||||
#include "../../FileManager/Resource/MessagesDialog/resource.rc"
|
||||
#include "../../FileManager/Resource/OverwriteDialog/resource.rc"
|
||||
#include "../../FileManager/Resource/PasswordDialog/resource.rc"
|
||||
#include "../../FileManager/Resource/ProgressDialog/resource.rc"
|
||||
#include "../../UI/Resource/Extract/resource.rc"
|
||||
#include "../../UI/FileManager/MessagesDialog.rc"
|
||||
#include "../../UI/FileManager/OverwriteDialog.rc"
|
||||
#include "../../UI/FileManager/PasswordDialog.rc"
|
||||
#include "../../UI/FileManager/ProgressDialog.rc"
|
||||
#include "../../UI/GUI/Extract.rc"
|
||||
|
||||
@@ -12,9 +12,13 @@
|
||||
|
||||
static inline HRESULT ConvertBoolToHRESULT(bool result)
|
||||
{
|
||||
// return result ? S_OK: E_FAIL;
|
||||
#ifdef _WIN32
|
||||
return result ? S_OK: (::GetLastError());
|
||||
if (result)
|
||||
return S_OK;
|
||||
DWORD lastError = ::GetLastError();
|
||||
if (lastError == 0)
|
||||
return E_FAIL;
|
||||
return lastError;
|
||||
#else
|
||||
return result ? S_OK: E_FAIL;
|
||||
#endif
|
||||
@@ -141,26 +145,13 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
|
||||
//////////////////////////
|
||||
// COutFileStream
|
||||
|
||||
bool COutFileStream::Create(LPCTSTR fileName, bool createAlways)
|
||||
{
|
||||
return File.Create(fileName, createAlways);
|
||||
}
|
||||
|
||||
#ifdef USE_WIN_FILE
|
||||
#ifndef _UNICODE
|
||||
bool COutFileStream::Create(LPCWSTR fileName, bool createAlways)
|
||||
{
|
||||
return File.Create(fileName, createAlways);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
#ifdef USE_WIN_FILE
|
||||
|
||||
UInt32 realProcessedSize;
|
||||
bool result = File.WritePart(data, size, realProcessedSize);
|
||||
ProcessedSize += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return ConvertBoolToHRESULT(result);
|
||||
@@ -174,13 +165,13 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
|
||||
return E_FAIL;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = (UInt32)res;
|
||||
ProcessedSize += res;
|
||||
return S_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
UInt64 *newPosition)
|
||||
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if(seekOrigin >= 3)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
|
||||
@@ -72,20 +72,52 @@ class COutFileStream:
|
||||
public IOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
#ifdef USE_WIN_FILE
|
||||
NWindows::NFile::NIO::COutFile File;
|
||||
#else
|
||||
NC::NFile::NIO::COutFile File;
|
||||
#endif
|
||||
public:
|
||||
virtual ~COutFileStream() {}
|
||||
bool Create(LPCTSTR fileName, bool createAlways);
|
||||
bool Create(LPCTSTR fileName, bool createAlways)
|
||||
{
|
||||
ProcessedSize = 0;
|
||||
return File.Create(fileName, createAlways);
|
||||
}
|
||||
bool Open(LPCTSTR fileName, DWORD creationDisposition)
|
||||
{
|
||||
ProcessedSize = 0;
|
||||
return File.Open(fileName, creationDisposition);
|
||||
}
|
||||
#ifdef USE_WIN_FILE
|
||||
#ifndef _UNICODE
|
||||
bool Create(LPCWSTR fileName, bool createAlways);
|
||||
bool Create(LPCWSTR fileName, bool createAlways)
|
||||
{
|
||||
ProcessedSize = 0;
|
||||
return File.Create(fileName, createAlways);
|
||||
}
|
||||
bool Open(LPCWSTR fileName, DWORD creationDisposition)
|
||||
{
|
||||
ProcessedSize = 0;
|
||||
return File.Open(fileName, creationDisposition);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UInt64 ProcessedSize;
|
||||
|
||||
#ifdef USE_WIN_FILE
|
||||
bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
|
||||
{
|
||||
return File.SetTime(creationTime, lastAccessTime, lastWriteTime);
|
||||
}
|
||||
bool SetLastWriteTime(const FILETIME *lastWriteTime)
|
||||
{
|
||||
return File.SetLastWriteTime(lastWriteTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
MY_UNKNOWN_IMP1(IOutStream)
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
@@ -109,7 +109,7 @@ HRESULT COutBuffer::Flush()
|
||||
|
||||
void COutBuffer::FlushWithCheck()
|
||||
{
|
||||
HRESULT result = FlushPart();
|
||||
HRESULT result = Flush();
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
ErrorCode = result;
|
||||
#else
|
||||
|
||||
@@ -4,52 +4,37 @@
|
||||
|
||||
#include "ProgressUtils.h"
|
||||
|
||||
void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress,
|
||||
const UInt64 *inStartValue, const UInt64 *outStartValue)
|
||||
CLocalProgress::CLocalProgress()
|
||||
{
|
||||
_progress = progress;
|
||||
_inStartValueIsAssigned = (inStartValue != NULL);
|
||||
if (_inStartValueIsAssigned)
|
||||
_inStartValue = *inStartValue;
|
||||
_outStartValueIsAssigned = (outStartValue != NULL);
|
||||
if (_outStartValueIsAssigned)
|
||||
_outStartValue = *outStartValue;
|
||||
ProgressOffset = InSize = OutSize = 0;
|
||||
SendRatio = true;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLocalCompressProgressInfo::SetRatioInfo(
|
||||
const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
UInt64 inSizeNew, outSizeNew;
|
||||
const UInt64 *inSizeNewPointer;
|
||||
const UInt64 *outSizeNewPointer;
|
||||
if (_inStartValueIsAssigned && inSize != NULL)
|
||||
{
|
||||
inSizeNew = _inStartValue + (*inSize);
|
||||
inSizeNewPointer = &inSizeNew;
|
||||
}
|
||||
else
|
||||
inSizeNewPointer = NULL;
|
||||
|
||||
if (_outStartValueIsAssigned && outSize != NULL)
|
||||
{
|
||||
outSizeNew = _outStartValue + (*outSize);
|
||||
outSizeNewPointer = &outSizeNew;
|
||||
}
|
||||
else
|
||||
outSizeNewPointer = NULL;
|
||||
return _progress->SetRatioInfo(inSizeNewPointer, outSizeNewPointer);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
|
||||
{
|
||||
_ratioProgress.Release();
|
||||
_progress = progress;
|
||||
_progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress);
|
||||
_inSizeIsMain = inSizeIsMain;
|
||||
}
|
||||
|
||||
STDMETHODIMP CLocalProgress::SetRatioInfo(
|
||||
const UInt64 *inSize, const UInt64 *outSize)
|
||||
STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
return _progress->SetCompleted(_inSizeIsMain ? inSize : outSize);
|
||||
UInt64 inSizeNew = InSize, outSizeNew = OutSize;
|
||||
if (inSize)
|
||||
inSizeNew += (*inSize);
|
||||
if (outSize)
|
||||
outSizeNew += (*outSize);
|
||||
if (SendRatio && _ratioProgress)
|
||||
{
|
||||
RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew));
|
||||
}
|
||||
inSizeNew += ProgressOffset;
|
||||
outSizeNew += ProgressOffset;
|
||||
return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew);
|
||||
}
|
||||
|
||||
HRESULT CLocalProgress::SetCur()
|
||||
{
|
||||
return SetRatioInfo(NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -8,32 +8,22 @@
|
||||
#include "../ICoder.h"
|
||||
#include "../IProgress.h"
|
||||
|
||||
class CLocalCompressProgressInfo:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ICompressProgressInfo> _progress;
|
||||
bool _inStartValueIsAssigned;
|
||||
bool _outStartValueIsAssigned;
|
||||
UInt64 _inStartValue;
|
||||
UInt64 _outStartValue;
|
||||
public:
|
||||
void Init(ICompressProgressInfo *progress,
|
||||
const UInt64 *inStartValue, const UInt64 *outStartValue);
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
};
|
||||
|
||||
class CLocalProgress:
|
||||
public ICompressProgressInfo,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<IProgress> _progress;
|
||||
CMyComPtr<ICompressProgressInfo> _ratioProgress;
|
||||
bool _inSizeIsMain;
|
||||
public:
|
||||
UInt64 ProgressOffset;
|
||||
UInt64 InSize;
|
||||
UInt64 OutSize;
|
||||
bool SendRatio;
|
||||
|
||||
CLocalProgress();
|
||||
void Init(IProgress *progress, bool inSizeIsMain);
|
||||
HRESULT SetCur();
|
||||
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size,
|
||||
size -= processedSizeLoc;
|
||||
RINOK(res);
|
||||
if (processedSizeLoc == 0)
|
||||
break;
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -238,6 +238,13 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
|
||||
|
||||
if (progress != NULL)
|
||||
{
|
||||
/*
|
||||
const UInt64 compressedSize =
|
||||
_mainStream.GetProcessedSize() +
|
||||
_callStream.GetProcessedSize() +
|
||||
_jumpStream.GetProcessedSize() +
|
||||
_rangeEncoder.GetProcessedSize();
|
||||
*/
|
||||
RINOK(progress->SetRatioInfo(&nowPos64, NULL));
|
||||
}
|
||||
|
||||
@@ -312,7 +319,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
|
||||
{
|
||||
if (processedBytes >= (1 << 20) && progress != NULL)
|
||||
{
|
||||
UInt64 nowPos64 = _outStream.GetProcessedSize();
|
||||
/*
|
||||
const UInt64 compressedSize =
|
||||
_mainInStream.GetProcessedSize() +
|
||||
_callStream.GetProcessedSize() +
|
||||
_jumpStream.GetProcessedSize() +
|
||||
_rangeDecoder.GetProcessedSize();
|
||||
*/
|
||||
const UInt64 nowPos64 = _outStream.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(NULL, &nowPos64));
|
||||
processedBytes = 0;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
|
||||
if (size > *outSize - TotalSize)
|
||||
size = (UInt32)(*outSize - TotalSize);
|
||||
RINOK(inStream->Read(_buffer, size, &realProcessedSize));
|
||||
if(realProcessedSize == 0)
|
||||
if (realProcessedSize == 0)
|
||||
break;
|
||||
RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
|
||||
TotalSize += realProcessedSize;
|
||||
|
||||
@@ -463,14 +463,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try
|
||||
{
|
||||
HRESULT res = CodeReal(inStream, outStream, inSize, outSize, progress);
|
||||
m_OutWindowStream.Flush();
|
||||
return res;
|
||||
}
|
||||
catch(const CLZOutWindowException &e) { m_OutWindowStream.Flush(); return e.ErrorCode; }
|
||||
catch(...) { m_OutWindowStream.Flush(); return S_FALSE; }
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
|
||||
|
||||
@@ -385,6 +385,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ CDecoder::CDecoder():
|
||||
CDecoder::~CDecoder()
|
||||
{
|
||||
InitFilters();
|
||||
if (_vmData)
|
||||
::MidFree(_vmData);
|
||||
::MidFree(_vmData);
|
||||
::MidFree(_window);
|
||||
}
|
||||
|
||||
HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size)
|
||||
@@ -821,6 +821,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
_unpackSize = *outSize;
|
||||
return CodeReal(progress);
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
// CNewException is possible here. But probably CNewException is caused
|
||||
// by error in data stream.
|
||||
|
||||
@@ -35,13 +35,12 @@ const UInt32 kLevelTableSize = 20;
|
||||
|
||||
const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize;
|
||||
|
||||
template<class TInByte>
|
||||
class CBitDecoder2
|
||||
class CBitDecoder
|
||||
{
|
||||
UInt32 m_Value;
|
||||
public:
|
||||
UInt32 m_BitPos;
|
||||
TInByte m_Stream;
|
||||
CInBuffer m_Stream;
|
||||
bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
|
||||
void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
|
||||
void ReleaseStream() { m_Stream.ReleaseStream();}
|
||||
@@ -98,8 +97,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef CBitDecoder2<CInBuffer> CBitDecoder;
|
||||
|
||||
const int kNumTopBits = 24;
|
||||
const UInt32 kTopValue = (1 << kNumTopBits);
|
||||
const UInt32 kBot = (1 << 15);
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
// FolderInterface.h
|
||||
|
||||
#ifndef __FOLDERINTERFACE_H
|
||||
#define __FOLDERINTERFACE_H
|
||||
|
||||
#include "../IProgress.h"
|
||||
|
||||
#define FOLDER_INTERFACE_SUB(i, b, x, y) \
|
||||
DEFINE_GUID(IID_ ## i, \
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, x, y, 0x00); \
|
||||
struct i: public b
|
||||
|
||||
#define FOLDER_INTERFACE2(i, x, y) FOLDER_INTERFACE_SUB(i, IUnknown, x, y)
|
||||
|
||||
#define FOLDER_INTERFACE(i, x) FOLDER_INTERFACE2(i, x, 0x00)
|
||||
|
||||
namespace NPlugin
|
||||
{
|
||||
enum
|
||||
{
|
||||
kName = 0,
|
||||
kType,
|
||||
kClassID,
|
||||
kOptionsClassID
|
||||
};
|
||||
}
|
||||
|
||||
FOLDER_INTERFACE(IFolderFolder, 0x00)
|
||||
{
|
||||
STDMETHOD(LoadItems)() PURE;
|
||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems) PURE;
|
||||
// STDMETHOD(GetNumberOfSubFolders)(UInt32 *numSubFolders) PURE;
|
||||
STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) PURE;
|
||||
STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder) PURE;
|
||||
STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) PURE;
|
||||
STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) PURE;
|
||||
STDMETHOD(GetName)(BSTR *name) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IEnumProperties, 0x01)
|
||||
{
|
||||
// STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE;
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) PURE;
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderGetTypeID, 0x02)
|
||||
{
|
||||
STDMETHOD(GetTypeID)(BSTR *name) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderGetPath, 0x03)
|
||||
{
|
||||
STDMETHOD(GetPath)(BSTR *path) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderWasChanged, 0x04)
|
||||
{
|
||||
STDMETHOD(WasChanged)(Int32 *wasChanged) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
FOLDER_INTERFACE(IFolderReload, 0x05)
|
||||
{
|
||||
STDMETHOD(Reload)() PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x06, 0x01)
|
||||
{
|
||||
STDMETHOD(AskWrite)(
|
||||
const wchar_t *srcPath,
|
||||
Int32 srcIsFolder,
|
||||
const FILETIME *srcTime,
|
||||
const UInt64 *srcSize,
|
||||
const wchar_t *destPathRequest,
|
||||
BSTR *destPathResult,
|
||||
Int32 *writeAnswer) PURE;
|
||||
STDMETHOD(ShowMessage)(const wchar_t *message) PURE;
|
||||
STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
FOLDER_INTERFACE_SUB(IFolderOperationsUpdateCallback, IProgress, 0x06, 0x02)
|
||||
{
|
||||
STDMETHOD(AskOverwrite)(
|
||||
const wchar_t *srcPath,
|
||||
Int32 destIsFolder,
|
||||
const FILETIME *destTime,
|
||||
const UInt64 *destSize,
|
||||
const wchar_t *aDestPathRequest,
|
||||
const wchar_t *aDestName,
|
||||
BSTR *aDestPathResult,
|
||||
Int32 *aResult);
|
||||
};
|
||||
*/
|
||||
|
||||
FOLDER_INTERFACE(IFolderOperations, 0x06)
|
||||
{
|
||||
STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) PURE;
|
||||
STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) PURE;
|
||||
STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress) PURE;
|
||||
STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE;
|
||||
STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE;
|
||||
STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE;
|
||||
STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
|
||||
const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) PURE;
|
||||
STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03)
|
||||
{
|
||||
STDMETHOD(DeleteToRecycleBin)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07)
|
||||
{
|
||||
STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08)
|
||||
{
|
||||
STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderClone, 0x09)
|
||||
{
|
||||
STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderSetFlatMode, 0x0A)
|
||||
{
|
||||
STDMETHOD(SetFlatMode)(Int32 flatMode) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
FOLDER_INTERFACE(IFolderOpen, 0x10)
|
||||
{
|
||||
STDMETHOD(FolderOpen)(
|
||||
const wchar_t *aFileName,
|
||||
// IArchiveHandler100 **anArchiveHandler,
|
||||
// NZipRootRegistry::CArchiverInfo &anArchiverInfoResult,
|
||||
// UString &aDefaultName,
|
||||
IOpenArchive2CallBack *anOpenArchive2CallBack) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
#define FOLDER_MANAGER_INTERFACE(i, x) \
|
||||
DEFINE_GUID(IID_ ## i, \
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, x, 0x00, 0x00); \
|
||||
struct i: public IUnknown
|
||||
|
||||
// old interfaces 00, 01
|
||||
|
||||
FOLDER_MANAGER_INTERFACE(IFolderManager, 0x02)
|
||||
{
|
||||
STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) PURE;
|
||||
STDMETHOD(GetExtensions)(BSTR *extensions) PURE;
|
||||
STDMETHOD(GetIconPath)(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) PURE;
|
||||
// STDMETHOD(GetTypes)(BSTR *types) PURE;
|
||||
// STDMETHOD(GetExtensions)(const wchar_t *type, BSTR *extensions) PURE;
|
||||
// STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE;
|
||||
};
|
||||
|
||||
/*
|
||||
FOLDER_MANAGER_INTERFACE(IFolderManagerGetIconPath, 0x03)
|
||||
{
|
||||
};
|
||||
*;/
|
||||
|
||||
/*
|
||||
FOLDER_INTERFACE(IFolderExtract, 0x05, 0x0A);
|
||||
{
|
||||
STDMETHOD(Clone)(IFolderFolder **aFolder) PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderChangeNotify,0x05, 0x04, 0x00);
|
||||
IFolderChangeNotify: public IUnknown
|
||||
{
|
||||
STDMETHOD(OnChanged)() PURE;
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderSetChangeNotify, 0x05, 0x05);
|
||||
{
|
||||
STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
// PhysDriveFolder.h
|
||||
|
||||
#ifndef __PHYSDRIVEFOLDER_H
|
||||
#define __PHYSDRIVEFOLDER_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "IFolder.h"
|
||||
|
||||
class CPhysDriveFolder:
|
||||
public IFolderFolder,
|
||||
public IEnumProperties,
|
||||
public IFolderGetTypeID,
|
||||
public IFolderGetPath,
|
||||
public IFolderWasChanged,
|
||||
public IFolderOperations,
|
||||
public IFolderGetItemFullSize,
|
||||
public IFolderClone,
|
||||
// public IFolderGetSystemIconIndex,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UInt64 GetSizeOfItem(int anIndex) const;
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN
|
||||
MY_QUERYINTERFACE_ENTRY(IEnumProperties)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetPath)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderWasChanged)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderClone)
|
||||
// MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex)
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
|
||||
STDMETHOD(LoadItems)();
|
||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
||||
STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
|
||||
STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
|
||||
STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
|
||||
STDMETHOD(GetName)(BSTR *name);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
STDMETHOD(GetTypeID)(BSTR *name);
|
||||
STDMETHOD(GetPath)(BSTR *path);
|
||||
STDMETHOD(WasChanged)(INT32 *wasChanged);
|
||||
STDMETHOD(Clone)(IFolderFolder **resultFolder);
|
||||
STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress);
|
||||
|
||||
// IFolderOperations
|
||||
STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress);
|
||||
STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress);
|
||||
STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress);
|
||||
STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress);
|
||||
STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback);
|
||||
STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback);
|
||||
STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath,
|
||||
const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress);
|
||||
STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress);
|
||||
// STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
|
||||
|
||||
private:
|
||||
UString _name;
|
||||
UString _prefix;
|
||||
UString _path;
|
||||
UString GetFullPath() const { return _prefix + _path; }
|
||||
UString GetFullPathWithName() const { return GetFullPath() + L'\\' + _name; }
|
||||
CMyComPtr<IFolderFolder> _parentFolder;
|
||||
|
||||
UINT _driveType;
|
||||
DISK_GEOMETRY geom;
|
||||
UInt64 _length;
|
||||
|
||||
public:
|
||||
HRESULT Init(const UString &path);
|
||||
HRESULT GetLength(UInt64 &size) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.9 KiB |
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,3 +0,0 @@
|
||||
#define IDD_DIALOG_LISTBOX 202
|
||||
|
||||
#define IDC_LISTBOX_LIST 1000
|
||||
@@ -1,22 +0,0 @@
|
||||
#include "resource.h"
|
||||
#include "../../../GuiCommon.rc"
|
||||
|
||||
#define xSize2 223
|
||||
#define ySize2 177
|
||||
|
||||
#define xSize (xSize2 + marg + marg)
|
||||
#define ySize (ySize2 + marg + marg)
|
||||
|
||||
#define bYPos (ySize - marg - bYSize)
|
||||
#define b1XPos (xSize - marg - bXSize)
|
||||
#define b2XPos (b1XPos - 10 - bXSize)
|
||||
|
||||
|
||||
IDD_DIALOG_LISTBOX DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
|
||||
CAPTION "List Box"
|
||||
MY_FONT
|
||||
BEGIN
|
||||
LISTBOX IDC_LISTBOX_LIST, marg, marg, xSize2, 149, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
|
||||
PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
|
||||
END
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
#include "resource.h"
|
||||
#include "../../../GuiCommon.rc"
|
||||
|
||||
#define xSize2 290
|
||||
#define ySize2 76
|
||||
|
||||
#define xSize (xSize2 + marg + marg)
|
||||
#define ySize (ySize2 + marg + marg)
|
||||
|
||||
#define bYPos (ySize - marg - bYSize)
|
||||
|
||||
#undef bXSize
|
||||
#define bXSize 72
|
||||
|
||||
#define bXPos1 (xSize - marg - bXSize)
|
||||
#define bXPos2 (bXPos1 - 10 - bXSize)
|
||||
#define bXPos3 (bXPos2 - 10 - bXSize)
|
||||
|
||||
#define valSize 42
|
||||
#define timeSize 91
|
||||
#define labelPos 178
|
||||
#define valPos1 (marg + timeSize)
|
||||
#define valPos2 (xSize - marg - valSize)
|
||||
#define labelSize (valPos2 - labelPos)
|
||||
|
||||
#undef yPos
|
||||
#define yPos (marg + 11)
|
||||
|
||||
|
||||
IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
|
||||
CAPTION "Progress"
|
||||
MY_FONT
|
||||
BEGIN
|
||||
PUSHBUTTON "&Background", IDC_BUTTON_PROGRESS_PRIORITY, bXPos3, bYPos, bXSize, bYSize
|
||||
PUSHBUTTON "&Pause", IDC_BUTTON_PAUSE, bXPos2, bYPos, bXSize, bYSize
|
||||
PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
|
||||
LTEXT "Elapsed time:", IDC_PROGRESS_ELAPSED, marg, marg, timeSize, 8
|
||||
LTEXT "Remaining time:", IDC_PROGRESS_REMAINING, marg, yPos, timeSize, 8
|
||||
LTEXT "Size:", IDC_PROGRESS_TOTAL, labelPos, marg, labelSize, 8
|
||||
LTEXT "Speed:", IDC_PROGRESS_SPEED, labelPos, yPos, labelSize, 8
|
||||
RTEXT "00:00:00", IDC_PROGRESS_ELAPSED_VALUE, valPos1, marg, valSize, 8
|
||||
RTEXT "", IDC_PROGRESS_REMAINING_VALUE, valPos1, yPos, valSize, 8
|
||||
RTEXT "", IDC_PROGRESS_SPEED_TOTAL_VALUE, valPos2, marg, valSize, 8
|
||||
RTEXT "", IDC_PROGRESS_SPEED_VALUE, valPos2, yPos, valSize, 8
|
||||
LTEXT "", IDC_PROGRESS_FILE_NAME, marg, yPos + 16, xSize2, 8, SS_NOPREFIX
|
||||
CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, marg, bYPos - 20, xSize2, 13
|
||||
END
|
||||
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_PROGRESS_PAUSED "Paused"
|
||||
IDS_PROGRESS_FOREGROUND "&Foreground"
|
||||
IDS_PROGRESS_CONTINUE "&Continue"
|
||||
IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?"
|
||||
END
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
// stdafx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#define _WIN32_WINNT 0x0400
|
||||
|
||||
// it's for Windows NT supporting (MENUITEMINFOW)
|
||||
#define WINVER 0x0400
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "Common/NewHandler.h"
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
// RootFolder.h
|
||||
|
||||
#ifndef __ROOTFOLDER_H
|
||||
#define __ROOTFOLDER_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "FSFolder.h"
|
||||
|
||||
class CRootFolder:
|
||||
public IFolderFolder,
|
||||
public IEnumProperties,
|
||||
public IFolderGetTypeID,
|
||||
public IFolderGetPath,
|
||||
public IFolderGetSystemIconIndex,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP4(
|
||||
IEnumProperties,
|
||||
IFolderGetTypeID,
|
||||
IFolderGetPath,
|
||||
IFolderGetSystemIconIndex
|
||||
)
|
||||
|
||||
STDMETHOD(LoadItems)();
|
||||
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
|
||||
STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value);
|
||||
STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder);
|
||||
STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder);
|
||||
STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder);
|
||||
STDMETHOD(GetName)(BSTR *name);
|
||||
|
||||
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
|
||||
STDMETHOD(GetPropertyInfo)(UInt32 index,
|
||||
BSTR *name, PROPID *propID, VARTYPE *varType);
|
||||
STDMETHOD(GetTypeID)(BSTR *name);
|
||||
STDMETHOD(GetPath)(BSTR *path);
|
||||
STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex);
|
||||
|
||||
void Init();
|
||||
private:
|
||||
UString _computerName;
|
||||
UString _networkName;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,104 +1,101 @@
|
||||
{23170F69-40C1-278A-0000-}
|
||||
{23170F69-40C1-278A-0000-00yy00xx0000}
|
||||
|
||||
000000xx0000 IProgress.h
|
||||
00 IProgress.h
|
||||
|
||||
05 IProgress
|
||||
05 IProgress
|
||||
|
||||
01 IFolderArchive.h
|
||||
|
||||
05 IArchiveFolder
|
||||
06 IInFolderArchive
|
||||
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
|
||||
0A IOutFolderArchive
|
||||
0B IFolderArchiveUpdateCallback
|
||||
0<> Agent.h::IArchiveFolderInternal
|
||||
|
||||
03 IStream.h
|
||||
|
||||
01 ISequentialInStream
|
||||
02 ISequentialOutStream
|
||||
03 IInStream
|
||||
04 IOutStream
|
||||
06 IStreamGetSize
|
||||
07 IOutStreamFlush
|
||||
|
||||
|
||||
000300xx0000 IStream.h
|
||||
04 ICoder.h
|
||||
|
||||
01 ISequentialInStream
|
||||
02 ISequentialOutStream
|
||||
03 IInStream
|
||||
04 IOutStream
|
||||
06 IStreamGetSize
|
||||
07 IOutStreamFlush
|
||||
04 ICompressProgressInfo
|
||||
05 ICompressCoder
|
||||
18 ICompressCoder2
|
||||
20 ICompressSetCoderProperties
|
||||
21 ICompressSetDecoderProperties //
|
||||
22 ICompressSetDecoderProperties2
|
||||
23 ICompressWriteCoderProperties
|
||||
24 ICompressGetInStreamProcessedSize
|
||||
25 ICompressSetCoderMt
|
||||
30 ICompressGetSubStreamSize
|
||||
31 ICompressSetInStream
|
||||
32 ICompressSetOutStream
|
||||
33 ICompressSetInStreamSize
|
||||
34 ICompressSetOutStreamSize
|
||||
40 ICompressFilter
|
||||
60 ICompressCodecsInfo
|
||||
61 ISetCompressCodecsInfo
|
||||
80 ICryptoProperties
|
||||
88 ICryptoResetSalt
|
||||
8C ICryptoResetInitVector
|
||||
90 ICryptoSetPassword
|
||||
A0 ICryptoSetCRC
|
||||
|
||||
|
||||
000400xx0000 ICoder.h
|
||||
05 IPassword.h
|
||||
|
||||
04 ICompressProgressInfo
|
||||
05 ICompressCoder
|
||||
18 ICompressCoder2
|
||||
20 ICompressSetCoderProperties
|
||||
21 ICompressSetDecoderProperties //
|
||||
22 ICompressSetDecoderProperties2
|
||||
23 ICompressWriteCoderProperties
|
||||
24 ICompressGetInStreamProcessedSize
|
||||
25 ICompressSetCoderMt
|
||||
30 ICompressGetSubStreamSize
|
||||
31 ICompressSetInStream
|
||||
32 ICompressSetOutStream
|
||||
33 ICompressSetInStreamSize
|
||||
34 ICompressSetOutStreamSize
|
||||
40 ICompressFilter
|
||||
60 ICompressCodecsInfo
|
||||
61 ISetCompressCodecsInfo
|
||||
80 ICryptoProperties
|
||||
88 ICryptoResetSalt
|
||||
8C ICryptoResetInitVector
|
||||
90 ICryptoSetPassword
|
||||
A0 ICryptoSetCRC
|
||||
10 ICryptoGetTextPassword
|
||||
11 ICryptoGetTextPassword2
|
||||
|
||||
|
||||
000500xx0000 IPassword.h
|
||||
06 IArchive.h
|
||||
|
||||
10 ICryptoGetTextPassword
|
||||
11 ICryptoGetTextPassword2
|
||||
03 ISetProperties
|
||||
|
||||
10 IArchiveOpenCallback
|
||||
20 IArchiveExtractCallback
|
||||
30 IArchiveOpenVolumeCallback
|
||||
40 IInArchiveGetStream
|
||||
50 IArchiveOpenSetSubArchiveName
|
||||
60 IInArchive
|
||||
|
||||
000600xx0000 IArchive.h
|
||||
|
||||
03 ISetProperties
|
||||
|
||||
10 IArchiveOpenCallback
|
||||
20 IArchiveExtractCallback
|
||||
30 IArchiveOpenVolumeCallback
|
||||
40 IInArchiveGetStream
|
||||
50 IArchiveOpenSetSubArchiveName
|
||||
60 IInArchive
|
||||
|
||||
80 IArchiveUpdateCallback
|
||||
82 IArchiveUpdateCallback2
|
||||
A0 IOutArchive
|
||||
|
||||
|
||||
000100050001 Agent.h::IArchiveFolderInternal
|
||||
|
||||
|
||||
000100xx0000 IFolderArchive.h
|
||||
|
||||
05 IArchiveFolder
|
||||
06 IInFolderArchive
|
||||
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
|
||||
0A IOutFolderArchive
|
||||
0B IFolderArchiveUpdateCallback
|
||||
80 IArchiveUpdateCallback
|
||||
82 IArchiveUpdateCallback2
|
||||
A0 IOutArchive
|
||||
|
||||
|
||||
|
||||
08 IFolder.h
|
||||
|
||||
000800xxyy00 FolderInterface.h::
|
||||
00 IFolderFolder
|
||||
01 IEnumProperties
|
||||
02 IFolderGetTypeID
|
||||
03 IFolderGetPath
|
||||
04 IFolderWasChanged
|
||||
05 // IFolderReload
|
||||
06 IFolderOperations
|
||||
07 IFolderGetSystemIconIndex
|
||||
08 IFolderGetItemFullSize
|
||||
09 IFolderClone
|
||||
0A IFolderSetFlatMode
|
||||
0B IFolderOperationsExtractCallback
|
||||
|
||||
00 IFolderFolder
|
||||
01 IEnumProperties
|
||||
02 IFolderGetTypeID
|
||||
03 IFolderGetPath
|
||||
04 IFolderWasChanged
|
||||
05 IFolderReload //
|
||||
0504 IFolderChangeNotify
|
||||
0505 IFolderSetChangeNotify
|
||||
050A IFolderExtract //
|
||||
06 IFolderOperations
|
||||
0601 IFolderOperationsExtractCallback
|
||||
0602 IFolderOperationsUpdateCallback //
|
||||
0603 IFolderOperationsDeleteToRecycleBin //
|
||||
07 IFolderGetSystemIconIndex
|
||||
08 IFolderGetItemFullSize
|
||||
09 IFolderClone
|
||||
0A IFolderSetFlatMode
|
||||
|
||||
000900000000} FolderInterface.h::IFolderManager
|
||||
000900010000} FolderInterface.h::IFolderManagerGetIconPath
|
||||
09 FolderInterface.h
|
||||
|
||||
00 // old IFolderManager
|
||||
01 IFolderManager
|
||||
|
||||
|
||||
|
||||
------------------
|
||||
|
||||
|
||||
{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu
|
||||
@@ -110,28 +107,28 @@ Handler GUIDs:
|
||||
|
||||
{23170F69-40C1-278A-1000-000110xx0000}
|
||||
|
||||
01 Zip
|
||||
02 BZip2
|
||||
03 Rar
|
||||
04 Arj
|
||||
05 Z
|
||||
06 Lzh
|
||||
07 7z
|
||||
08 Cab
|
||||
09 Nsis
|
||||
0A Lzma
|
||||
01 Zip
|
||||
02 BZip2
|
||||
03 Rar
|
||||
04 Arj
|
||||
05 Z
|
||||
06 Lzh
|
||||
07 7z
|
||||
08 Cab
|
||||
09 Nsis
|
||||
0A Lzma
|
||||
|
||||
E5 Compound
|
||||
E6 Wim
|
||||
E7 Iso
|
||||
E8 Bkf
|
||||
E9 Chm
|
||||
EA Split
|
||||
EB Rpm
|
||||
EC Deb
|
||||
ED Cpio
|
||||
EE Tar
|
||||
EF GZip
|
||||
E5 Compound
|
||||
E6 Wim
|
||||
E7 Iso
|
||||
E8 Bkf
|
||||
E9 Chm
|
||||
EA Split
|
||||
EB Rpm
|
||||
EC Deb
|
||||
ED Cpio
|
||||
EE Tar
|
||||
EF GZip
|
||||
|
||||
{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle
|
||||
{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu
|
||||
@@ -142,4 +139,3 @@ EF GZip
|
||||
|
||||
{23170F69-40C1-2790-id} Codec Decoders
|
||||
{23170F69-40C1-2791-id} Codec Encoders
|
||||
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
|
||||
#include "IStream.h"
|
||||
|
||||
// "23170F69-40C1-278A-0000-000400xx0000"
|
||||
#define CODER_INTERFACE(i, x) \
|
||||
DEFINE_GUID(IID_ ## i, \
|
||||
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
|
||||
struct i: public IUnknown
|
||||
#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)
|
||||
|
||||
CODER_INTERFACE(ICompressProgressInfo, 0x04)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user