4.53 beta

This commit is contained in:
Igor Pavlov
2007-08-27 00:00:00 +00:00
committed by Kornel Lesiński
parent 33ccab7e72
commit 051769bbc5
360 changed files with 4658 additions and 5167 deletions

View File

@@ -13,7 +13,9 @@
#include "../../Common/CreateCoder.h" #include "../../Common/CreateCoder.h"
#include "../../Common/FilterCoder.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 NArchive {
namespace N7z { namespace N7z {
@@ -59,7 +61,8 @@ HRESULT CEncoder::CreateMixerCoder(
{ {
const CMethodFull &methodFull = _options.Methods[i]; const CMethodFull &methodFull = _options.Methods[i];
_codersInfo.Add(CCoderInfo()); _codersInfo.Add(CCoderInfo());
// CCoderInfo &encodingInfo = _codersInfo.Back(); CCoderInfo &encodingInfo = _codersInfo.Back();
encodingInfo.MethodID = methodFull.Id;
CMyComPtr<ICompressCoder> encoder; CMyComPtr<ICompressCoder> encoder;
CMyComPtr<ICompressCoder2> encoder2; CMyComPtr<ICompressCoder2> encoder2;
@@ -176,7 +179,7 @@ HRESULT CEncoder::Encode(
return E_FAIL; return E_FAIL;
UInt32 mainCoderIndex, mainStreamIndex; UInt32 mainCoderIndex, mainStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex); _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
if (inStreamSize != NULL) if (inStreamSize != NULL)
{ {
CRecordVector<const UInt64 *> sizePointers; 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, RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress)); &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));

View File

@@ -149,16 +149,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
); );
// CDecoder1 decoder; // CDecoder1 decoder;
UInt64 currentImportantTotalUnPacked = 0; UInt64 currentTotalPacked = 0;
UInt64 currentTotalUnPacked = 0;
UInt64 totalFolderUnPacked; UInt64 totalFolderUnPacked;
UInt64 totalFolderPacked;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for(int i = 0; i < extractFolderInfoVector.Size(); i++, 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]; const CExtractFolderInfo &efi = extractFolderInfoVector[i];
totalFolderUnPacked = efi.UnPackSize; totalFolderUnPacked = efi.UnPackSize;
RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked)); totalFolderPacked = 0;
CFolderOutStream *folderOutStream = new CFolderOutStream; CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream); CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
@@ -194,14 +205,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CNum folderIndex = efi.FolderIndex; CNum folderIndex = efi.FolderIndex;
const CFolder &folderInfo = database.Folders[folderIndex]; const CFolder &folderInfo = database.Folders[folderIndex];
CLocalProgress *localProgressSpec = new CLocalProgress; totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, NULL, &currentImportantTotalUnPacked);
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex]; CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0); UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
@@ -225,7 +229,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
&database.PackSizes[packStreamIndex], &database.PackSizes[packStreamIndex],
folderInfo, folderInfo,
outStream, outStream,
compressProgress progress
#ifndef _NO_CRYPTO #ifndef _NO_CRYPTO
, getTextPassword , getTextPassword
#endif #endif

View File

@@ -53,14 +53,10 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
}
#ifdef _SFX #ifdef _SFX
IMP_IInArchive_ArcProps_NO
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */) STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
{ {
return E_NOTIMPL; return E_NOTIMPL;
@@ -72,27 +68,64 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
return E_NOTIMPL; 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 #endif
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
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)
{ {
if (timeDefined) if (timeDefined)
propVariant = unixTime; prop = unixTime;
} }
#ifndef _SFX #ifndef _SFX
@@ -171,7 +204,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
/* /*
const CRef2 &ref2 = _refs[index]; const CRef2 &ref2 = _refs[index];
@@ -196,68 +229,68 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
case kpidPath: case kpidPath:
{ {
if (!item.Name.IsEmpty()) if (!item.Name.IsEmpty())
propVariant = NItemName::GetOSName(item.Name); prop = NItemName::GetOSName(item.Name);
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory; prop = item.IsDirectory;
break; break;
case kpidSize: case kpidSize:
{ {
propVariant = item.UnPackSize; prop = item.UnPackSize;
// propVariant = ref2.UnPackSize; // prop = ref2.UnPackSize;
break; break;
} }
case kpidPosition: case kpidPosition:
{ {
/* /*
if (ref2.Refs.Size() > 1) if (ref2.Refs.Size() > 1)
propVariant = ref2.StartPos; prop = ref2.StartPos;
else else
*/ */
if (item.IsStartPosDefined) if (item.IsStartPosDefined)
propVariant = item.StartPos; prop = item.StartPos;
break; break;
} }
case kpidPackedSize: case kpidPackedSize:
{ {
// propVariant = ref2.PackSize; // prop = ref2.PackSize;
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
{ {
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2) if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
propVariant = _database.GetFolderFullPackSize(folderIndex); prop = _database.GetFolderFullPackSize(folderIndex);
/* /*
else else
propVariant = UInt64(0); prop = (UInt64)0;
*/ */
} }
else else
propVariant = UInt64(0); prop = (UInt64)0;
} }
break; break;
} }
case kpidLastAccessTime: case kpidLastAccessTime:
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant); MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
break; break;
case kpidCreationTime: case kpidCreationTime:
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant); MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant); MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
break; break;
case kpidAttributes: case kpidAttributes:
if (item.AreAttributesDefined) if (item.AreAttributesDefined)
propVariant = item.Attributes; prop = item.Attributes;
break; break;
case kpidCRC: case kpidCRC:
if (item.IsFileCRCDefined) if (item.IsFileCRCDefined)
propVariant = item.FileCRC; prop = item.FileCRC;
break; break;
case kpidEncrypted: case kpidEncrypted:
{ {
propVariant = IsEncrypted(index2); prop = IsEncrypted(index2);
break; break;
} }
#ifndef _SFX #ifndef _SFX
@@ -357,7 +390,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
} }
} }
propVariant = methodsString; prop = methodsString;
} }
} }
break; break;
@@ -365,7 +398,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{ {
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2]; CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex) if (folderIndex != kNumNoIndex)
propVariant = (UInt32)folderIndex; prop = (UInt32)folderIndex;
} }
break; break;
case kpidPackedSize0: case kpidPackedSize0:
@@ -381,21 +414,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 && if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0)) folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
{ {
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0); prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
} }
else else
propVariant = UInt64(0); prop = (UInt64)0;
} }
else else
propVariant = UInt64(0); prop = (UInt64)0;
} }
break; break;
#endif #endif
case kpidIsAnti: case kpidIsAnti:
propVariant = item.IsAnti; prop = item.IsAnti;
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -522,11 +555,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{ {
UString baseName; UString baseName;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (propVariant.vt != VT_BSTR) if (prop.vt != VT_BSTR)
break; break;
baseName = propVariant.bstrVal; baseName = prop.bstrVal;
} }
seqName.InitName(baseName); seqName.InitName(baseName);
} }

View File

@@ -170,6 +170,13 @@ struct CArchiveDatabase
NumUnPackStreamsVector.IsEmpty() && NumUnPackStreamsVector.IsEmpty() &&
Files.IsEmpty()); Files.IsEmpty());
} }
bool IsSolid() const
{
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
if (NumUnPackStreamsVector[i] > 1)
return true;
return false;
}
}; };
}} }}

View File

@@ -37,18 +37,14 @@ CPropMap kPropMap[] =
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4}, { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4}, { NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCRC, NULL, kpidCRC, 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}, // { 97, NULL, kpidSolid, VT_BOOL},
#ifndef _SFX #ifndef _SFX
{ 98, NULL, kpidMethod, VT_BSTR}, { 98, NULL, kpidMethod, VT_BSTR},
{ 99, L"Block", kpidBlock, VT_UI4} { 99, NULL, kpidBlock, VT_UI4}
#endif #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]); static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);

View File

@@ -22,52 +22,19 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
static const UInt32 kAlgorithmForBCJ2_LZMA = 1; static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64; static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
static HRESULT CopyBlock(ISequentialInStream *inStream, static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
ISequentialOutStream *outStream, ICompressProgressInfo *progress) UInt64 position, UInt64 size, ICompressProgressInfo *progress)
{ {
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
return copyCoder->Code(inStream, outStream, NULL, NULL, progress); CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
}
static HRESULT WriteRange(
ISequentialInStream *inStream,
ISequentialOutStream *outStream,
UInt64 size,
IProgress *progress,
UInt64 &currentComplexity)
{
CLimitedSequentialInStream *streamSpec = new
CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec); CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
streamSpec->SetStream(inStream); streamSpec->SetStream(inStream);
streamSpec->Init(size); streamSpec->Init(size);
CLocalProgress *localProgressSpec = new CLocalProgress; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
localProgressSpec->Init(progress, true); RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(localProgress, &currentComplexity, &currentComplexity);
HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
currentComplexity += size;
return result;
}
static HRESULT WriteRange(IInStream *inStream,
ISequentialOutStream *outStream,
UInt64 position,
UInt64 size,
IProgress *progress,
UInt64 &currentComplexity)
{
inStream->Seek(position, STREAM_SEEK_SET, 0);
return WriteRange(inStream, outStream,
size, progress, currentComplexity);
} }
static int GetReverseSlashPos(const UString &name) static int GetReverseSlashPos(const UString &name)
@@ -94,14 +61,6 @@ UString CUpdateItem::GetExtension() const
return Name.Mid(GetExtensionPos()); return Name.Mid(GetExtensionPos());
} }
/*
struct CFolderRef
{
const CArchiveDatabaseEx *Database;
int FolderIndex;
};
*/
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
@@ -522,16 +481,10 @@ static HRESULT Update2(
return E_NOTIMPL; return E_NOTIMPL;
*/ */
UInt64 startBlockSize = database != 0 ? UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
database->ArchiveInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock) if (startBlockSize > 0 && !options.RemoveSfxBlock)
{ {
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
streamSpec->SetStream(inStream);
streamSpec->Init(startBlockSize);
RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
} }
CRecordVector<int> fileIndexToUpdateIndexMap; CRecordVector<int> fileIndexToUpdateIndexMap;
@@ -607,6 +560,11 @@ static HRESULT Update2(
complexity = 0; complexity = 0;
RINOK(updateCallback->SetCompleted(&complexity)); RINOK(updateCallback->SetCompleted(&complexity));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
///////////////////////////////////////// /////////////////////////////////////////
// Write Copy Items // Write Copy Items
@@ -614,10 +572,11 @@ static HRESULT Update2(
{ {
int folderIndex = folderRefs[i]; int folderIndex = folderRefs[i];
lps->ProgressOffset = complexity;
UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream, RINOK(WriteRange(inStream, archive.SeqStream,
database->GetFolderStreamPos(folderIndex, 0), database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
database->GetFolderFullPackSize(folderIndex), complexity += packSize;
updateCallback, complexity));
const CFolder &folder = database->Folders[folderIndex]; const CFolder &folder = database->Folders[folderIndex];
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex]; CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
@@ -736,18 +695,17 @@ static HRESULT Update2(
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles); inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
CFolder folderItem; 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( RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
solidInStream, NULL, &inSizeForReduce, folderItem, 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() // for()
// newDatabase.PackCRCsDefined.Add(false); // newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0); // newDatabase.PackCRCs.Add(0);
@@ -783,7 +741,6 @@ static HRESULT Update2(
file.IsFileCRCDefined = true; file.IsFileCRCDefined = true;
file.HasStream = true; file.HasStream = true;
numUnPackStreams++; numUnPackStreams++;
complexity += file.UnPackSize;
} }
else else
{ {
@@ -935,8 +892,7 @@ HRESULT UpdateVolume(
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec; CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
inCrcStreamSpec->Init(fileStream); inCrcStreamSpec->Init(fileStream);
RINOK(WriteRange(inCrcStream, volumeStream, pureSize, RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
updateCallback, complexity));
file.UnPackSize = inCrcStreamSpec->GetSize(); file.UnPackSize = inCrcStreamSpec->GetSize();
if (file.UnPackSize == 0) if (file.UnPackSize == 0)
break; break;

View File

@@ -85,11 +85,11 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
if (formatIndex >= g_NumArcs) if (formatIndex >= g_NumArcs)
return E_INVALIDARG; return E_INVALIDARG;
const CArcInfo &arc = *g_Arcs[formatIndex]; const CArcInfo &arc = *g_Arcs[formatIndex];
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
case NArchive::kName: case NArchive::kName:
propVariant = arc.Name; prop = arc.Name;
break; break;
case NArchive::kClassID: case NArchive::kClassID:
{ {
@@ -99,22 +99,22 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
} }
case NArchive::kExtension: case NArchive::kExtension:
if (arc.Ext != 0) if (arc.Ext != 0)
propVariant = arc.Ext; prop = arc.Ext;
break; break;
case NArchive::kAddExtension: case NArchive::kAddExtension:
if (arc.AddExt != 0) if (arc.AddExt != 0)
propVariant = arc.AddExt; prop = arc.AddExt;
break; break;
case NArchive::kUpdate: case NArchive::kUpdate:
propVariant = (bool)(arc.CreateOutArchive != 0); prop = (bool)(arc.CreateOutArchive != 0);
break; break;
case NArchive::kKeepName: case NArchive::kKeepName:
propVariant = arc.KeepName; prop = arc.KeepName;
break; break;
case NArchive::kStartSignature: case NArchive::kStartSignature:
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value); return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
} }

View File

@@ -51,16 +51,7 @@ const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
const wchar_t *kUnknownOS = L"Unknown"; const wchar_t *kUnknownOS = L"Unknown";
/* STATPROPSTG kProps[] =
enum // PropID
{
kpidHostOS = kpidUserDefined,
kpidUnPackVersion,
kpidMethod,
};
*/
STATPROPSTG kProperties[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -68,59 +59,15 @@ STATPROPSTG kProperties[] =
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidLastWriteTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4}, { NULL, kpidAttributes, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL}, { NULL, kpidEncrypted, VT_BOOL},
// { NULL, kpidCommented, VT_BOOL},
{ NULL, kpidCRC, VT_UI4}, { NULL, kpidCRC, VT_UI4},
{ NULL, kpidMethod, VT_UI1}, { NULL, kpidMethod, VT_UI1},
// { NULL, kpidUnpackVer, VT_UI1},
{ NULL, kpidHostOS, VT_BSTR} { NULL, kpidHostOS, VT_BSTR}
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
// { L"Method", kpidMethod, VT_UI1},
// { L"Host OS", kpidHostOS, VT_BSTR}
}; };
IMP_IInArchive_Props
CHandler::CHandler() IMP_IInArchive_ArcProps_NO
{}
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;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
@@ -131,27 +78,19 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = _items[index]; const CItemEx &item = _items[index];
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
propVariant = case kpidIsFolder: prop = item.IsDirectory(); break;
NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); case kpidSize: prop = item.Size; break;
/* case kpidPackedSize: prop = item.PackSize; break;
NItemName::GetOSName2( case kpidAttributes: prop = item.GetWinAttributes(); break;
MultiByteToUnicodeString(item.Name, item.GetCodePage())); case kpidEncrypted: prop = item.IsEncrypted(); break;
*/ case kpidCRC: prop = item.FileCRC; break;
break; case kpidMethod: prop = item.Method; break;
case kpidIsFolder: case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
propVariant = item.IsDirectory();
break;
case kpidSize:
propVariant = item.Size;
break;
case kpidPackedSize:
propVariant = item.PackSize;
break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
FILETIME localFileTime, utcFileTime; FILETIME localFileTime, utcFileTime;
@@ -162,52 +101,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
else else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
propVariant = utcFileTime; prop = utcFileTime;
break; 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; return S_OK;
COM_TRY_END 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, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
{ {
@@ -226,17 +128,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
} }
for (;;) for (;;)
{ {
CItemEx itemInfo; CItemEx item;
bool filled; bool filled;
HRESULT result = archive.GetNextItem(filled, itemInfo); HRESULT result = archive.GetNextItem(filled, item);
if (result == S_FALSE) if (result == S_FALSE)
return S_FALSE; return S_FALSE;
if (result != S_OK) if (result != S_OK)
return S_FALSE; return S_FALSE;
if (!filled) if (!filled)
break; break;
_items.Add(itemInfo); _items.Add(item);
archive.IncreaseRealPosition(itemInfo.PackSize); archive.IncreaseRealPosition(item.PackSize);
if (callback != NULL) if (callback != NULL)
{ {
UInt64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
@@ -279,9 +181,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt32 i; UInt32 i;
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
{ {
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; const CItemEx &item = _items[allFilesMode ? i : indices[i]];
totalUnPacked += itemInfo.Size; totalUnPacked += item.Size;
totalPacked += itemInfo.PackSize; totalPacked += item.PackSize;
} }
extractCallback->SetTotal(totalUnPacked); extractCallback->SetTotal(totalUnPacked);
@@ -290,29 +192,40 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CMyComPtr<ICompressCoder> arj1Decoder; CMyComPtr<ICompressCoder> arj1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder; 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, for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked) currentTotalPacked += currentItemPacked)
{ {
currentItemUnPacked = 0; lps->InSize = currentTotalPacked;
currentItemPacked = 0; lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
currentItemUnPacked = currentItemPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalUnPacked));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode = testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
const CItemEx &itemInfo = _items[index]; const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if(itemInfo.IsDirectory()) if(item.IsDirectory())
{ {
// if (!testMode) // if (!testMode)
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
} }
continue; continue;
} }
@@ -321,8 +234,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
currentItemUnPacked = itemInfo.Size; currentItemUnPacked = item.Size;
currentItemPacked = itemInfo.PackSize; currentItemPacked = item.PackSize;
{ {
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
@@ -331,68 +244,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
outStreamSpec->Init(); outStreamSpec->Init();
realOutStream.Release(); realOutStream.Release();
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; streamSpec->Init(item.PackSize);
CMyComPtr<ISequentialInStream> inStream(streamSpec);
UInt64 pos; UInt64 pos;
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
streamSpec->SetStream(_stream); HRESULT result = S_OK;
streamSpec->Init(itemInfo.PackSize); Int32 opRes = NExtract::NOperationResult::kOK;
if (item.IsEncrypted())
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalPacked,
&currentTotalUnPacked);
if (itemInfo.IsEncrypted())
{ {
RINOK(extractCallback->SetOperationResult( opRes = NExtract::NOperationResult::kUnSupportedMethod;
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
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 else
{ {
result = copyCoder->Code(inStream, outStream, switch(item.Method)
NULL, NULL, compressProgress);
}
if (result == S_FALSE)
throw "data error";
if (result != S_OK)
return result;
}
catch(...)
{ {
outStream.Release(); case NFileHeader::NCompressionMethod::kStored:
RINOK(extractCallback->SetOperationResult( {
NArchive::NExtract::NOperationResult::kDataError)); result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
continue; if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
} result = S_FALSE;
break; break;
} }
case NFileHeader::NCompressionMethod::kCompressed1a: case NFileHeader::NCompressionMethod::kCompressed1a:
@@ -400,80 +272,35 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
case NFileHeader::NCompressionMethod::kCompressed1c: case NFileHeader::NCompressionMethod::kCompressed1c:
{ {
if (!arj1Decoder) if (!arj1Decoder)
{
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder; arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
} result = arj1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
try
{
if (itemInfo.IsEncrypted())
{
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
else
{
result = arj1Decoder->Code(inStream, outStream,
NULL, &currentItemUnPacked, 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; break;
} }
case NFileHeader::NCompressionMethod::kCompressed2: case NFileHeader::NCompressionMethod::kCompressed2:
{ {
if (!arj2Decoder) if (!arj2Decoder)
{
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder; arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
} result = arj2Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
try
{
if (itemInfo.IsEncrypted())
{
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
else
{
result = arj2Decoder->Code(inStream, outStream,
NULL, &currentItemUnPacked, 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; break;
} }
default: default:
RINOK(extractCallback->SetOperationResult( opRes = NExtract::NOperationResult::kUnSupportedMethod;
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
} }
bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC; }
outStream.Release(); if (opRes == NExtract::NOperationResult::kOK)
if(crcOK) {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else else
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) {
RINOK(result);
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kCRCError;
}
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
} }
} }
return S_OK; return S_OK;

View File

@@ -19,7 +19,6 @@ public:
INTERFACE_IInArchive(;) INTERFACE_IInArchive(;)
CHandler();
private: private:
CObjectVector<CItemEx> _items; CObjectVector<CItemEx> _items;
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;

View File

@@ -21,49 +21,13 @@ namespace NBZip2 {
static const CMethodId kMethodId_BZip2 = 0x040202; static const CMethodId kMethodId_BZip2 = 0x040202;
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPackedSize, VT_UI8}
// { NULL, kpidIsFolder, VT_BOOL},
// { NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8},
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
@@ -71,24 +35,15 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK; 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 prop;
NWindows::NCOM::CPropVariant propVariant;
if (index != 0)
return E_INVALIDARG;
switch(propID) switch(propID)
{ {
case kpidIsFolder: case kpidPackedSize: prop = _item.PackSize; break;
propVariant = false;
break;
case kpidPackedSize:
propVariant = _item.PackSize;
break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END
} }
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
@@ -148,14 +103,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
extractCallback->SetTotal(_item.PackSize); extractCallback->SetTotal(_item.PackSize);
UInt64 currentTotalPacked = 0, currentTotalUnPacked = 0; UInt64 currentTotalPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalPacked)); RINOK(extractCallback->SetCompleted(&currentTotalPacked));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : askMode = testMode ? NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
@@ -171,7 +126,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
kMethodId_BZip2, decoder, false); kMethodId_BZip2, decoder, false);
if (loadResult != S_OK || !decoder) if (loadResult != S_OK || !decoder)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
return S_OK; return S_OK;
} }
@@ -188,29 +143,26 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CDummyOutStream *outStreamSpec = new CDummyOutStream; CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream); outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release(); realOutStream.Release();
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(extractCallback, true); lps->Init(extractCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
HRESULT result = S_OK; HRESULT result = S_OK;
bool firstItem = true; bool firstItem = true;
for (;;) for (;;)
{ {
localCompressProgressSpec->Init(progress, lps->InSize = currentTotalPacked;
&currentTotalPacked, lps->OutSize = outStreamSpec->GetSize();
&currentTotalUnPacked);
RINOK(lps->SetCur());
const int kSignatureSize = 3; const int kSignatureSize = 3;
Byte buffer[kSignatureSize]; Byte buffer[kSignatureSize];
@@ -226,26 +178,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
{ {
if (firstItem) if (firstItem)
return E_FAIL; return E_FAIL;
outStream.Release(); break;
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
return S_OK;
} }
firstItem = false; firstItem = false;
UInt64 dataStartPos; UInt64 dataStartPos;
RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &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) if (result != S_OK)
break; break;
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize);
&getInStreamProcessedSize);
if (!getInStreamProcessedSize) if (!getInStreamProcessedSize)
break; break;
UInt64 packSize; UInt64 packSize;
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize)); RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
UInt64 pos; UInt64 pos;
@@ -254,17 +202,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
} }
outStream.Release(); outStream.Release();
int retResult; Int32 retResult;
if (result == S_OK) if (result == S_OK)
retResult = NArchive::NExtract::NOperationResult::kOK; retResult = NExtract::NOperationResult::kOK;
else if (result == S_FALSE) else if (result == S_FALSE)
retResult = NArchive::NExtract::NOperationResult::kDataError; retResult = NExtract::NOperationResult::kDataError;
else else
return result; return result;
return extractCallback->SetOperationResult(retResult);
RINOK(extractCallback->SetOperationResult(retResult));
return S_OK;
COM_TRY_END COM_TRY_END
} }

View File

@@ -49,20 +49,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UInt32 indexInArchive; UInt32 indexInArchive;
if (!updateCallback) if (!updateCallback)
return E_FAIL; return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(0, RINOK(updateCallback->GetUpdateItemInfo(0,&newData, &newProperties, &indexInArchive));
&newData, &newProperties, &indexInArchive));
if (IntToBool(newProperties)) if (IntToBool(newProperties))
{ {
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &propVariant)); RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop));
if (propVariant.vt == VT_BOOL) if (prop.vt == VT_BOOL)
{ {
if (propVariant.boolVal != VARIANT_FALSE) if (prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG; return E_INVALIDARG;
} }
else if (propVariant.vt != VT_EMPTY) else if (prop.vt != VT_EMPTY)
return E_INVALIDARG; return E_INVALIDARG;
} }
} }
@@ -71,11 +70,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{ {
UInt64 size; UInt64 size;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = propVariant.uhVal.QuadPart; size = prop.uhVal.QuadPart;
} }
UInt32 dicSize = _dicSize; UInt32 dicSize = _dicSize;

View File

@@ -14,6 +14,8 @@
#include "CabHandler.h" #include "CabHandler.h"
#include "CabBlockInStream.h" #include "CabBlockInStream.h"
#include "../../Common/ProgressUtils.h"
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#include "../../Compress/Deflate/DeflateDecoder.h" #include "../../Compress/Deflate/DeflateDecoder.h"
#include "../../Compress/Lzx/LzxDecoder.h" #include "../../Compress/Lzx/LzxDecoder.h"
@@ -31,13 +33,11 @@ namespace NCab {
#ifdef _CAB_DETAILS #ifdef _CAB_DETAILS
enum enum
{ {
kpidBlockReal = kpidUserDefined, kpidBlockReal = kpidUserDefined
kpidOffset,
kpidVolume,
}; };
#endif #endif
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL}, // { NULL, kpidIsFolder, VT_BOOL},
@@ -49,8 +49,8 @@ STATPROPSTG kProperties[] =
#ifdef _CAB_DETAILS #ifdef _CAB_DETAILS
, ,
{ L"BlockReal", kpidBlockReal, VT_UI4}, { L"BlockReal", kpidBlockReal, VT_UI4},
{ L"Offset", kpidOffset, VT_UI4}, { NULL, kpidOffset, VT_UI4},
{ L"Volume", kpidVolume, VT_UI4} { NULL, kpidVolume, VT_UI4}
#endif #endif
}; };
@@ -65,49 +65,69 @@ static const wchar_t *kMethods[] =
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
static const wchar_t *kUnknownMethod = L"Unknown"; static const wchar_t *kUnknownMethod = L"Unknown";
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) STATPROPSTG kArcProps[] =
{ {
value->vt = VT_EMPTY; { NULL, kpidMethod, VT_BSTR},
return S_OK; // { NULL, kpidSolid, VT_BOOL},
} { NULL, kpidNumBlocks, VT_UI4},
{ NULL, kpidNumVolumes, VT_UI4}
};
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
BSTR *name, PROPID *propID, VARTYPE *varType)
{ {
if(index >= sizeof(kProperties) / sizeof(kProperties[0])) COM_TRY_BEGIN
return E_INVALIDARG; NWindows::NCOM::CPropVariant prop;
const STATPROPSTG &srcItem = kProperties[index]; switch(propID)
*propID = srcItem.propid; {
*varType = srcItem.vt; case kpidMethod:
if (srcItem.lpwstrName == 0) {
*name = 0; UString resString;
else CRecordVector<Byte> ids;
*name = ::SysAllocString(srcItem.lpwstrName); int i;
return S_OK; 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++)
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{ {
*numProperties = 0; Byte id = ids[i];
return S_OK; UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
if (!resString.IsEmpty())
resString += L' ';
resString += method;
} }
prop = resString;
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, break;
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) }
// case kpidSolid: prop = _database.IsSolid(); break;
case kpidNumBlocks:
{ {
return E_INVALIDARG; 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;
COM_TRY_END
} }
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CMvItem &mvItem = m_Database.Items[index]; const CMvItem &mvItem = m_Database.Items[index];
const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; 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); ConvertUTF8ToUnicode(item.Name, unicodeName);
else else
unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP); unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP);
propVariant = (const wchar_t *)NItemName::WinNameToOSName(unicodeName); prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidSize: case kpidSize:
propVariant = item.Size; prop = item.Size;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
@@ -141,11 +161,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
} }
else else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
propVariant = utcFileTime; prop = utcFileTime;
break; break;
} }
case kpidAttributes: case kpidAttributes:
propVariant = item.GetWinAttributes(); prop = item.GetWinAttributes();
break; break;
case kpidMethod: case kpidMethod:
@@ -162,28 +182,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
ConvertUInt64ToString(folder.CompressionTypeMinor, temp); ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
method += temp; method += temp;
} }
propVariant = method; prop = method;
break; break;
} }
case kpidBlock: case kpidBlock:
propVariant = (Int32)m_Database.GetFolderIndex(&mvItem); prop = (Int32)m_Database.GetFolderIndex(&mvItem);
break; break;
#ifdef _CAB_DETAILS #ifdef _CAB_DETAILS
case kpidBlockReal: case kpidBlockReal:
propVariant = UInt32(item.FolderIndex); prop = UInt32(item.FolderIndex);
break; break;
case kpidOffset: case kpidOffset:
propVariant = (UInt32)item.Offset; prop = (UInt32)item.Offset;
break; break;
case kpidVolume: case kpidVolume:
propVariant = (UInt32)mvItem.VolumeIndex; prop = (UInt32)mvItem.VolumeIndex;
break; break;
#endif #endif
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -568,8 +588,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
totalUnPacked = 0; totalUnPacked = 0;
NCompress::CCopyCoder *copyCoderSpec = NULL; UInt64 totalPacked = 0;
CMyComPtr<ICompressCoder> copyCoder;
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; NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL;
CMyComPtr<ICompressCoder> deflateDecoder; CMyComPtr<ICompressCoder> deflateDecoder;
@@ -648,7 +674,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
curUnpack = item.GetEndOffset(); curUnpack = item.GetEndOffset();
} }
RINOK(extractCallback->SetCompleted(&totalUnPacked)); lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream; CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream); CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
@@ -662,11 +690,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
switch(folder.GetCompressionMethod()) switch(folder.GetCompressionMethod())
{ {
case NHeader::NCompressionMethodMajor::kNone: case NHeader::NCompressionMethodMajor::kNone:
if(copyCoderSpec == NULL)
{
copyCoderSpec = new NCompress::CCopyCoder;
copyCoder = copyCoderSpec;
}
break; break;
case NHeader::NCompressionMethodMajor::kMSZip: case NHeader::NCompressionMethodMajor::kMSZip:
if(deflateDecoderSpec == NULL) if(deflateDecoderSpec == NULL)
@@ -748,9 +771,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if (keepInputBuffer) if (keepInputBuffer)
continue; continue;
UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder();
RINOK(extractCallback->SetCompleted(&totalUnPacked2)); totalPacked += packSize;
lps->OutSize = totalUnPacked2;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
UInt64 unpackRemain = cabFolderOutStream->GetRemain(); UInt64 unpackRemain = cabFolderOutStream->GetRemain();
const UInt32 kBlockSizeMax = (1 << 15); const UInt32 kBlockSizeMax = (1 << 15);

View File

@@ -34,13 +34,12 @@ namespace NChm {
enum enum
{ {
kpidSection = kpidUserDefined, kpidSection = kpidUserDefined
kpidOffset
}; };
#endif #endif
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL}, // { NULL, kpidIsFolder, VT_BOOL},
@@ -51,62 +50,63 @@ STATPROPSTG kProperties[] =
#ifdef _CHM_DETAILS #ifdef _CHM_DETAILS
, ,
{ L"Section", kpidSection, VT_UI4}, { L"Section", kpidSection, VT_UI4},
{ L"Offset", kpidOffset, VT_UI4} { NULL, kpidOffset, VT_UI4}
#endif #endif
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) STATPROPSTG kArcProps[] =
{ {
value->vt = VT_EMPTY; { NULL, kpidNumBlocks, VT_UI8}
return S_OK; };
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) IMP_IInArchive_Props
{
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, IMP_IInArchive_ArcProps_NO
BSTR *name, PROPID *propID, VARTYPE *varType) /*
{ IMP_IInArchive_ArcProps
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) 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; 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) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
if (m_Database.NewFormat) if (m_Database.NewFormat)
{ {
switch(propID) switch(propID)
{ {
case kpidSize: case kpidSize:
propVariant = (UInt64)m_Database.NewFormatString.Length(); prop = (UInt64)m_Database.NewFormatString.Length();
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
} }
int entryIndex; int entryIndex;
@@ -128,44 +128,44 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (us[0] == L'/') if (us[0] == L'/')
us.Delete(0); us.Delete(0);
} }
propVariant = NItemName::GetOSName2(us); prop = NItemName::GetOSName2(us);
} }
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidSize: case kpidSize:
propVariant = item.Size; prop = item.Size;
break; break;
case kpidMethod: case kpidMethod:
{ {
if (!item.IsDirectory()) if (!item.IsDirectory())
if (item.Section == 0) if (item.Section == 0)
propVariant = L"Copy"; prop = L"Copy";
else if (item.Section < m_Database.Sections.Size()) 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; break;
} }
case kpidBlock: case kpidBlock:
if (m_Database.LowLevel) if (m_Database.LowLevel)
propVariant = item.Section; prop = item.Section;
else if (item.Section != 0) else if (item.Section != 0)
propVariant = m_Database.GetFolder(index); prop = m_Database.GetFolder(index);
break; break;
#ifdef _CHM_DETAILS #ifdef _CHM_DETAILS
case kpidSection: case kpidSection:
propVariant = (UInt32)item.Section; prop = (UInt32)item.Section;
break; break;
case kpidOffset: case kpidOffset:
propVariant = (UInt32)item.Offset; prop = (UInt32)item.Offset;
break; break;
#endif #endif
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -427,11 +427,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 currentTotalSize = 0; UInt64 currentTotalSize = 0;
CMyComPtr<ICompressCoder> copyCoder; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
UInt32 i; UInt32 i;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec); CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(m_Stream);
if (m_Database.LowLevel) if (m_Database.LowLevel)
{ {
@@ -446,10 +452,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&currentTotalSize)); currentItemSize = 0;
lps->InSize = currentTotalSize; // Change it
lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode= testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -488,22 +498,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
} }
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->SetStream(m_Stream);
streamSpec->Init(item.Size); streamSpec->Init(item.Size);
CLocalProgress *localProgressSpec = new CLocalProgress; RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, &currentTotalSize, &currentTotalSize);
if(!copyCoder)
copyCoder = new NCompress::CCopyCoder;
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress));
realOutStream.Release(); 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; return S_OK;
} }
@@ -566,13 +567,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue; continue;
} }
CLocalProgress *localProgressSpec = new CLocalProgress; lps->InSize = currentTotalSize; // Change it
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; lps->OutSize = currentTotalSize;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, NULL, &currentTotalSize);
if (item.Size == 0 || sectionIndex == 0) if (item.Size == 0 || sectionIndex == 0)
{ {
@@ -581,17 +577,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if (!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
Int32 opRes = NArchive::NExtract::NOperationResult::kOK;
if (!testMode && item.Size != 0) if (!testMode && item.Size != 0)
{ {
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->SetStream(m_Stream);
streamSpec->Init(item.Size); streamSpec->Init(item.Size);
if(!copyCoder) RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
copyCoder = new NCompress::CCopyCoder; if (copyCoderSpec->TotalSize != item.Size)
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); opRes = NArchive::NExtract::NOperationResult::kDataError;
} }
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(opRes));
currentTotalSize += item.Size; currentTotalSize += item.Size;
continue; continue;
} }

View File

@@ -10,7 +10,7 @@
namespace NArchive { namespace NArchive {
namespace NCom { namespace NCom {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -21,49 +21,32 @@ STATPROPSTG kProperties[] =
{ NULL, kpidLastWriteTime, VT_FILETIME} { 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]); { NULL, kpidClusterSize, VT_UI4}
return S_OK; };
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, IMP_IInArchive_Props
BSTR *name, PROPID *propID, VARTYPE *varType) IMP_IInArchive_ArcProps
{
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) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
*numProperties = 0; COM_TRY_BEGIN
return S_OK; NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; break;
} }
prop.Detach(value);
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, return S_OK;
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) COM_TRY_END
{
return E_INVALIDARG;
} }
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CRef &ref = _db.Refs[index]; const CRef &ref = _db.Refs[index];
const CItem &item = _db.Items[ref.Did]; const CItem &item = _db.Items[ref.Did];
@@ -72,21 +55,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath: case kpidPath:
{ {
UString name = _db.GetItemPath(index); UString name = _db.GetItemPath(index);
propVariant = name; prop = name;
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDir(); prop = item.IsDir();
break; break;
case kpidCreationTime: case kpidCreationTime:
propVariant = item.CreationTime; prop = item.CreationTime;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
propVariant = item.LastWriteTime; prop = item.LastWriteTime;
break; break;
/* /*
case kpidAttributes: case kpidAttributes:
propVariant = item.Falgs; prop = item.Falgs;
break; break;
*/ */
case kpidPackedSize: case kpidPackedSize:
@@ -95,15 +78,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
int numBits = _db.IsLargeStream(item.Size) ? int numBits = _db.IsLargeStream(item.Size) ?
_db.SectorSizeBits : _db.SectorSizeBits :
_db.MiniSectorSizeBits; _db.MiniSectorSizeBits;
propVariant = (item.Size + ((UInt32)1 << numBits) - 1) >> numBits << numBits; prop = (item.Size + ((UInt64)1 << numBits) - 1) >> numBits << numBits;
break; break;
} }
case kpidSize: case kpidSize:
if (!item.IsDir()) if (!item.IsDir())
propVariant = (UInt64)item.Size; prop = (UInt64)item.Size;
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }

View File

@@ -338,7 +338,7 @@ HRESULT OpenArchive(IInStream *inStream, CDatabase &db)
if (!db.MiniSids.Allocate(numSectorsInMiniStream)) if (!db.MiniSids.Allocate(numSectorsInMiniStream))
return S_FALSE; return S_FALSE;
{ {
UInt64 matSize64 = (root.Size + (1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits; UInt64 matSize64 = (root.Size + ((UInt64)1 << miniSectorSizeBits) - 1) >> miniSectorSizeBits;
if (matSize64 > NFatID::kMaxValue) if (matSize64 > NFatID::kMaxValue)
return S_FALSE; return S_FALSE;
db.MatSize = (UInt32)matSize64; db.MatSize = (UInt32)matSize64;

View File

@@ -8,6 +8,6 @@
static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; } static IInArchive *CreateArc() { return new NArchive::NCom::CHandler; }
static CArcInfo g_ArcInfo = 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) REGISTER_ARC(Com)

View File

@@ -167,6 +167,14 @@ HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStre
return S_OK; 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, STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
const UInt64 ** /* inSizes */, const UInt64 ** /* inSizes */,
UInt32 numInStreams, UInt32 numInStreams,
@@ -198,18 +206,10 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
if (i != _progressCoderIndex) if (i != _progressCoderIndex)
_coders[i].WaitFinish(); _coders[i].WaitFinish();
for (i = 0; i < _coders.Size(); i++) RINOK(ReturnIfError(E_ABORT));
{ RINOK(ReturnIfError(E_OUTOFMEMORY));
HRESULT result = _coders[i].Result; RINOK(ReturnIfError(S_FALSE));
if (result == E_ABORT)
return result;
}
for (i = 0; i < _coders.Size(); i++)
{
HRESULT result = _coders[i].Result;
if (result == S_FALSE)
return result;
}
for (i = 0; i < _coders.Size(); i++) for (i = 0; i < _coders.Size(); i++)
{ {
HRESULT result = _coders[i].Result; HRESULT result = _coders[i].Result;

View File

@@ -51,6 +51,7 @@ class CCoderMixer2MT:
void AddCoderCommon(); void AddCoderCommon();
HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams); HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
HRESULT ReturnIfError(HRESULT code);
public: public:
CObjectVector<CCoder2> _coders; CObjectVector<CCoder2> _coders;
MY_UNKNOWN_IMP MY_UNKNOWN_IMP

View File

@@ -30,6 +30,14 @@ void CCoderMixerMT::ReInit()
_coders[i].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, STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, const UInt64 * /* inSize */, const UInt64 * /* outSize */,
@@ -67,18 +75,10 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
if (i != _progressCoderIndex) if (i != _progressCoderIndex)
_coders[i].WaitFinish(); _coders[i].WaitFinish();
for (i = 0; i < _coders.Size(); i++) RINOK(ReturnIfError(E_ABORT));
{ RINOK(ReturnIfError(E_OUTOFMEMORY));
HRESULT result = _coders[i].Result; RINOK(ReturnIfError(S_FALSE));
if (result == E_ABORT)
return result;
}
for (i = 0; i < _coders.Size(); i++)
{
HRESULT result = _coders[i].Result;
if (result == S_FALSE)
return result;
}
for (i = 0; i < _coders.Size(); i++) for (i = 0; i < _coders.Size(); i++)
{ {
HRESULT result = _coders[i].Result; HRESULT result = _coders[i].Result;

View File

@@ -42,6 +42,7 @@ class CCoderMixerMT:
CObjectVector<CStreamBinder> _streamBinders; CObjectVector<CStreamBinder> _streamBinders;
int _progressCoderIndex; int _progressCoderIndex;
HRESULT ReturnIfError(HRESULT code);
public: public:
CObjectVector<CCoder> _coders; CObjectVector<CCoder> _coders;
MY_UNKNOWN_IMP MY_UNKNOWN_IMP

View File

@@ -4,17 +4,19 @@
#include "DummyOutStream.h" #include "DummyOutStream.h"
void CDummyOutStream::Init(ISequentialOutStream *outStream) STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{ {
m_Stream = outStream; UInt32 realProcessedSize;
HRESULT result;
if(!_stream)
{
realProcessedSize = size;
result = S_OK;
} }
else
STDMETHODIMP CDummyOutStream::Write(const void *data, result = _stream->Write(data, size, &realProcessedSize);
UInt32 size, UInt32 *processedSize) _size += realProcessedSize;
{
if(m_Stream)
return m_Stream->Write(data, size, processedSize);
if(processedSize != NULL) if(processedSize != NULL)
*processedSize = size; *processedSize = realProcessedSize;
return S_OK; return result;
} }

View File

@@ -10,14 +10,14 @@ class CDummyOutStream:
public ISequentialOutStream, public ISequentialOutStream,
public CMyUnknownImp public CMyUnknownImp
{ {
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
public: public:
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
void Init() { _size = 0; }
MY_UNKNOWN_IMP MY_UNKNOWN_IMP
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
private: UInt64 GetSize() const { return _size; }
CMyComPtr<ISequentialOutStream> m_Stream;
public:
void Init(ISequentialOutStream *outStream);
}; };
#endif #endif

View File

@@ -3,6 +3,7 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "CpioHandler.h" #include "CpioHandler.h"
#include "CpioIn.h"
#include "Common/Defs.h" #include "Common/Defs.h"
#include "Common/StringConvert.h" #include "Common/StringConvert.h"
@@ -16,8 +17,8 @@
#include "../../Common//LimitedStreams.h" #include "../../Common//LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
#include "CpioIn.h"
using namespace NWindows; using namespace NWindows;
using namespace NTime; using namespace NTime;
@@ -25,13 +26,15 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NCpio { namespace NCpio {
/*
enum // PropID enum // PropID
{ {
kpidinode = kpidUserDefined, kpidinode = kpidUserDefined,
kpidiChkSum kpidiChkSum
}; };
*/
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -44,43 +47,10 @@ STATPROPSTG kProperties[] =
// { L"CheckSum", kpidiChkSum, VT_UI4} // { L"CheckSum", kpidiChkSum, VT_UI4}
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
value->vt = VT_EMPTY;
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) STDMETHODIMP CHandler::Open(IInStream *stream,
{
*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,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback *openArchiveCallback) IArchiveOpenCallback *openArchiveCallback)
{ {
@@ -89,41 +59,41 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
{ {
CInArchive archive; CInArchive archive;
if(archive.Open(inStream) != S_OK) if (archive.Open(stream) != S_OK)
return S_FALSE; return S_FALSE;
m_Items.Clear(); _items.Clear();
if (openArchiveCallback != NULL) if (openArchiveCallback != NULL)
{ {
RINOK(openArchiveCallback->SetTotal(NULL, NULL)); RINOK(openArchiveCallback->SetTotal(NULL, NULL));
UInt64 numFiles = m_Items.Size(); UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
} }
for (;;) for (;;)
{ {
CItemEx itemInfo; CItemEx item;
bool filled; bool filled;
HRESULT result = archive.GetNextItem(filled, itemInfo); HRESULT result = archive.GetNextItem(filled, item);
if (result == S_FALSE) if (result == S_FALSE)
return S_FALSE; return S_FALSE;
if (result != S_OK) if (result != S_OK)
return S_FALSE; return S_FALSE;
if (!filled) if (!filled)
break; break;
m_Items.Add(itemInfo); _items.Add(item);
archive.SkeepDataRecords(itemInfo.Size, itemInfo.Align); archive.SkeepDataRecords(item.Size, item.Align);
if (openArchiveCallback != NULL) if (openArchiveCallback != NULL)
{ {
UInt64 numFiles = m_Items.Size(); UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL)); RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
} }
} }
if (m_Items.Size() == 0) if (_items.Size() == 0)
return S_FALSE; return S_FALSE;
m_InStream = inStream; _inStream = stream;
} }
/* /*
catch(...) catch(...)
@@ -137,35 +107,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
STDMETHODIMP CHandler::Close() STDMETHODIMP CHandler::Close()
{ {
m_Items.Clear(); _items.Clear();
m_InStream.Release(); _inStream.Release();
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
*numItems = m_Items.Size(); *numItems = _items.Size();
return S_OK; return S_OK;
} }
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = m_Items[index]; const CItemEx &item = _items[index];
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
propVariant = (const wchar_t *)NItemName::GetOSName( prop = (const wchar_t *)NItemName::GetOSName(
MultiByteToUnicodeString(item.Name, CP_OEMCP)); MultiByteToUnicodeString(item.Name, CP_OEMCP));
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
propVariant = item.Size; prop = (UInt64)item.Size;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
@@ -177,19 +147,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
utcFileTime.dwLowDateTime = 0; utcFileTime.dwLowDateTime = 0;
utcFileTime.dwHighDateTime = 0; utcFileTime.dwHighDateTime = 0;
} }
propVariant = utcFileTime; prop = utcFileTime;
break; break;
} }
case kpidinode:
propVariant = item.inode;
break;
/* /*
case kpidinode:
prop = item.inode;
break;
case kpidiChkSum: case kpidiChkSum:
propVariant = item.ChkSum; prop = item.ChkSum;
break; break;
*/ */
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -198,89 +168,65 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 _aTestMode, IArchiveExtractCallback *extractCallback) Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
bool testMode = (_aTestMode != 0);
bool allFilesMode = (numItems == UInt32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
numItems = m_Items.Size(); numItems = _items.Size();
if (numItems == 0) if (numItems == 0)
return S_OK; return S_OK;
bool testMode = (_aTestMode != 0);
UInt64 totalSize = 0; UInt64 totalSize = 0;
UInt32 i; UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
totalSize += m_Items[allFilesMode ? i : indices[i]].Size; totalSize += _items[allFilesMode ? i : indices[i]].Size;
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0; UInt64 currentTotalSize = 0;
UInt64 currentItemSize; 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) for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&currentTotalSize)); lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode = testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
const CItemEx &itemInfo = m_Items[index]; const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
currentItemSize = item.Size;
currentItemSize = itemInfo.Size; if (item.IsDirectory())
if(itemInfo.IsDirectory())
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
if (!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
{
continue; continue;
}
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
{
if (testMode) if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
RINOK(m_InStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); streamSpec->Init(item.Size);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
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,
&currentTotalSize, &currentTotalSize);
if(copyCoder == NULL)
{
copyCoder = new NCompress::CCopyCoder;
}
try
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
continue; NArchive::NExtract::NOperationResult::kOK:
} NArchive::NExtract::NOperationResult::kDataError));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END

View File

@@ -21,8 +21,8 @@ public:
INTERFACE_IInArchive(;) INTERFACE_IInArchive(;)
private: private:
CObjectVector<CItemEx> m_Items; CObjectVector<CItemEx> _items;
CMyComPtr<IInStream> m_InStream; CMyComPtr<IInStream> _inStream;
}; };
}} }}

View File

@@ -26,51 +26,16 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NDeb { namespace NDeb {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME} { NULL, kpidLastWriteTime, VT_FILETIME}
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
@@ -92,17 +57,17 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
for (;;) for (;;)
{ {
CItemEx itemInfo; CItemEx item;
bool filled; bool filled;
HRESULT result = archive.GetNextItem(filled, itemInfo); HRESULT result = archive.GetNextItem(filled, item);
if (result == S_FALSE) if (result == S_FALSE)
return S_FALSE; return S_FALSE;
if (result != S_OK) if (result != S_OK)
return S_FALSE; return S_FALSE;
if (!filled) if (!filled)
break; break;
_items.Add(itemInfo); _items.Add(item);
archive.SkeepData(itemInfo.Size); archive.SkeepData(item.Size);
if (openArchiveCallback != NULL) if (openArchiveCallback != NULL)
{ {
UInt64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
@@ -131,21 +96,21 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = _items[index]; const CItemEx &item = _items[index];
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
propVariant = (const wchar_t *)NItemName::GetOSName2( prop = (const wchar_t *)NItemName::GetOSName2(
MultiByteToUnicodeString(item.Name, CP_OEMCP)); MultiByteToUnicodeString(item.Name, CP_OEMCP));
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = false; prop = false;
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
propVariant = item.Size; prop = item.Size;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
@@ -157,11 +122,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
utcFileTime.dwLowDateTime = 0; utcFileTime.dwLowDateTime = 0;
utcFileTime.dwHighDateTime = 0; utcFileTime.dwHighDateTime = 0;
} }
propVariant = utcFileTime; prop = utcFileTime;
break; break;
} }
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -170,12 +135,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 _aTestMode, IArchiveExtractCallback *extractCallback) Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
bool testMode = (_aTestMode != 0);
bool allFilesMode = (numItems == UInt32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
numItems = _items.Size(); numItems = _items.Size();
if (numItems == 0) if (numItems == 0)
return S_OK; return S_OK;
bool testMode = (_aTestMode != 0);
UInt64 totalSize = 0; UInt64 totalSize = 0;
UInt32 i; UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
@@ -185,68 +150,50 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 currentTotalSize = 0; UInt64 currentTotalSize = 0;
UInt64 currentItemSize; 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) for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&currentTotalSize)); lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode = testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
const CItemEx &itemInfo = _items[index]; const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
currentItemSize = item.Size;
currentItemSize = itemInfo.Size;
if (!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
{
continue; continue;
}
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
{
if (testMode) if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
RINOK(_inStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL)); streamSpec->Init(item.Size);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
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,
&currentTotalSize, &currentTotalSize);
if(copyCoder == NULL)
{
copyCoder = new NCompress::CCopyCoder;
}
try
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
continue; NArchive::NExtract::NOperationResult::kOK:
} NArchive::NExtract::NOperationResult::kDataError));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END

View File

@@ -59,15 +59,13 @@ enum // PropID
}; };
*/ */
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidLastWriteTime, VT_FILETIME},
// { NULL, kpidCommented, VT_BOOL},
// { NULL, kpidMethod, VT_UI1}, // { NULL, kpidMethod, VT_UI1},
{ NULL, kpidHostOS, VT_BSTR}, { NULL, kpidHostOS, VT_BSTR},
@@ -77,39 +75,8 @@ STATPROPSTG kProperties[] =
// { L"Is Text", kpidIsText, VT_BOOL}, // { L"Is Text", kpidIsText, VT_BOOL},
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
@@ -120,15 +87,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
if (m_Item.NameIsPresent()) if (m_Item.NameIsPresent())
propVariant = MultiByteToUnicodeString(m_Item.Name, CP_ACP); prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP);
break;
case kpidIsFolder:
propVariant = false;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
@@ -136,47 +100,47 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
if (m_Item.Time != 0) if (m_Item.Time != 0)
{ {
NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime); NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime);
propVariant = utcTime; prop = utcTime;
} }
else else
{ {
// utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0; // utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0;
// propVariant = utcTime; // prop = utcTime;
} }
break; break;
} }
case kpidSize: case kpidSize:
propVariant = UInt64(m_Item.UnPackSize32); prop = UInt64(m_Item.UnPackSize32);
break; break;
case kpidPackedSize: case kpidPackedSize:
propVariant = m_PackSize; prop = m_PackSize;
break; break;
case kpidCommented: case kpidCommented:
propVariant = m_Item.CommentIsPresent(); prop = m_Item.CommentIsPresent();
break; break;
case kpidHostOS: case kpidHostOS:
propVariant = (m_Item.HostOS < kNumHostOSes) ? prop = (m_Item.HostOS < kNumHostOSes) ?
kHostOS[m_Item.HostOS] : kUnknownOS; kHostOS[m_Item.HostOS] : kUnknownOS;
break; break;
case kpidMethod: case kpidMethod:
propVariant = m_Item.CompressionMethod; prop = m_Item.CompressionMethod;
break; break;
case kpidCRC: case kpidCRC:
propVariant = m_Item.FileCRC; prop = m_Item.FileCRC;
break; break;
/* /*
case kpidExtraFlags: case kpidExtraFlags:
propVariant = m_Item.ExtraFlags; prop = m_Item.ExtraFlags;
break; break;
case kpidIsText: case kpidIsText:
propVariant = m_Item.IsText(); prop = m_Item.IsText();
break; break;
case kpidExtraIsPresent: case kpidExtraIsPresent:
propVariant = m_Item.ExtraFieldIsPresent(); prop = m_Item.ExtraFieldIsPresent();
break; break;
*/ */
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -232,7 +196,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
extractCallback->SetTotal(m_PackSize); extractCallback->SetTotal(m_PackSize);
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; UInt64 currentTotalPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalPacked)); RINOK(extractCallback->SetCompleted(&currentTotalPacked));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
@@ -253,22 +217,18 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
outStreamSpec->Init(); outStreamSpec->Init();
realOutStream.Release(); realOutStream.Release();
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(extractCallback, true); lps->Init(extractCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
CMyComPtr<ICompressCoder> deflateDecoder; CMyComPtr<ICompressCoder> deflateDecoder;
bool firstItem = true; bool firstItem = true;
RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL)); RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
Int32 opRes;
for (;;) for (;;)
{ {
localCompressProgressSpec->Init(progress, lps->InSize = currentTotalPacked;
&currentTotalPacked, lps->OutSize = outStreamSpec->GetSize();
&currentTotalUnPacked);
CInArchive archive; CInArchive archive;
CItem item; CItem item;
@@ -277,9 +237,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
{ {
if (firstItem) if (firstItem)
return E_FAIL; return E_FAIL;
outStream.Release(); opRes = NArchive::NExtract::NOperationResult::kOK;
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) break;
return S_OK;
} }
firstItem = false; firstItem = false;
@@ -288,10 +247,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
outStreamSpec->InitCRC(); outStreamSpec->InitCRC();
switch(item.CompressionMethod) if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflate)
{
case NFileHeader::NCompressionMethod::kDeflate:
{ {
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
break;
}
if (!deflateDecoder) if (!deflateDecoder)
{ {
RINOK(CreateCoder( RINOK(CreateCoder(
@@ -299,34 +260,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
kMethodId_Deflate, deflateDecoder, false)); kMethodId_Deflate, deflateDecoder, false));
if (!deflateDecoder) if (!deflateDecoder)
{ {
outStream.Release(); opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
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;
}
break; 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; CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
&getInStreamProcessedSize)); &getInStreamProcessedSize));
@@ -342,12 +288,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
return E_FAIL; return E_FAIL;
if((outStreamSpec->GetCRC() != postItem.FileCRC)) if((outStreamSpec->GetCRC() != postItem.FileCRC))
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) opRes = NArchive::NExtract::NOperationResult::kCRCError;
break; break;
} }
} }
outStream.Release();
return extractCallback->SetOperationResult(opRes);
COM_TRY_END COM_TRY_END
return S_OK;
} }
IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo

View File

@@ -70,41 +70,41 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UString name; UString name;
bool isDirectory; bool isDirectory;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &propVariant)); RINOK(updateCallback->GetProperty(itemIndex, kpidAttributes, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
attributes = 0; attributes = 0;
else if (propVariant.vt != VT_UI4) else if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
else else
attributes = propVariant.ulVal; attributes = prop.ulVal;
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &propVariant)); RINOK(updateCallback->GetProperty(itemIndex, kpidLastWriteTime, &prop));
if (propVariant.vt != VT_FILETIME) if (prop.vt != VT_FILETIME)
return E_INVALIDARG; return E_INVALIDARG;
utcTime = propVariant.filetime; utcTime = prop.filetime;
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &propVariant)); RINOK(updateCallback->GetProperty(itemIndex, kpidPath, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
name.Empty(); name.Empty();
else if (propVariant.vt != VT_BSTR) else if (prop.vt != VT_BSTR)
return E_INVALIDARG; return E_INVALIDARG;
else else
name = propVariant.bstrVal; name = prop.bstrVal;
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &propVariant)); RINOK(updateCallback->GetProperty(itemIndex, kpidIsFolder, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
isDirectory = false; isDirectory = false;
else if (propVariant.vt != VT_BOOL) else if (prop.vt != VT_BOOL)
return E_INVALIDARG; return E_INVALIDARG;
else else
isDirectory = (propVariant.boolVal != VARIANT_FALSE); isDirectory = (prop.boolVal != VARIANT_FALSE);
} }
if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes)) if (isDirectory || NFile::NFind::NAttributes::IsDirectory(attributes))
return E_INVALIDARG; return E_INVALIDARG;
@@ -121,11 +121,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (IntToBool(newData)) if (IntToBool(newData))
{ {
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(itemIndex, kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = propVariant.uhVal.QuadPart; size = prop.uhVal.QuadPart;
} }
newItem.UnPackSize32 = (UInt32)size; newItem.UnPackSize32 = (UInt32)size;

View File

@@ -34,9 +34,7 @@ HRESULT UpdateArchive(
int indexInClient, int indexInClient,
IArchiveUpdateCallback *updateCallback) IArchiveUpdateCallback *updateCallback)
{ {
UInt64 complexity = 0; UInt64 complexity = unpackSize;
complexity += unpackSize;
RINOK(updateCallback->SetTotal(complexity)); RINOK(updateCallback->SetTotal(complexity));
@@ -54,13 +52,9 @@ HRESULT UpdateArchive(
inStreamSpec->SetStream(fileInStream); inStreamSpec->SetStream(fileInStream);
inStreamSpec->Init(); inStreamSpec->Init();
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(updateCallback, true); lps->Init(updateCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
COutArchive outArchive; COutArchive outArchive;
outArchive.Create(outStream); outArchive.Create(outStream);
@@ -72,8 +66,6 @@ HRESULT UpdateArchive(
RINOK(outArchive.WriteHeader(item)); RINOK(outArchive.WriteHeader(item));
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
{ {
RINOK(CreateCoder( RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
@@ -102,7 +94,7 @@ HRESULT UpdateArchive(
RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); 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.FileCRC = inStreamSpec->GetCRC();
item.UnPackSize32 = (UInt32)inStreamSpec->GetSize(); item.UnPackSize32 = (UInt32)inStreamSpec->GetSize();

View File

@@ -7,12 +7,7 @@
#include "../IProgress.h" #include "../IProgress.h"
#include "../PropID.h" #include "../PropID.h"
// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000") #define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
#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(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) #define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
namespace NFileTimeType 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 #endif

View File

@@ -15,6 +15,7 @@
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
@@ -25,7 +26,7 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NIso { namespace NIso {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -34,41 +35,8 @@ STATPROPSTG kProperties[] =
{ NULL, kpidLastWriteTime, VT_FILETIME} { NULL, kpidLastWriteTime, VT_FILETIME}
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
STDMETHODIMP CHandler::Open(IInStream *stream, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
@@ -103,7 +71,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
if (index >= (UInt32)_archive.Refs.Size()) if (index >= (UInt32)_archive.Refs.Size())
{ {
index -= _archive.Refs.Size(); index -= _archive.Refs.Size();
@@ -118,16 +86,16 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
// s += name; // s += name;
// s += L"-"; // s += L"-";
s += be.GetName(); s += be.GetName();
propVariant = (const wchar_t *)s; prop = (const wchar_t *)s;
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = false; prop = false;
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
{ {
propVariant = (UInt64)_archive.GetBootItemSize(index); prop = (UInt64)_archive.GetBootItemSize(index);
break; break;
} }
} }
@@ -154,22 +122,22 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (!s.IsEmpty()) if (!s.IsEmpty())
if (s[s.Length() - 1] == L'.') if (s[s.Length() - 1] == L'.')
s = s.Left(s.Length() - 1); s = s.Left(s.Length() - 1);
propVariant = (const wchar_t *)NItemName::GetOSName2(s); prop = (const wchar_t *)NItemName::GetOSName2(s);
} }
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDir(); prop = item.IsDir();
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
if (!item.IsDir()) if (!item.IsDir())
propVariant = (UInt64)item.DataLength; prop = (UInt64)item.DataLength;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
FILETIME utcFileTime; FILETIME utcFileTime;
if (item.DateTime.GetFileTime(utcFileTime)) if (item.DateTime.GetFileTime(utcFileTime))
propVariant = utcFileTime; prop = utcFileTime;
/* /*
else else
{ {
@@ -181,7 +149,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
} }
} }
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -194,9 +162,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
bool allFilesMode = (numItems == UInt32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
numItems = _archive.Refs.Size(); numItems = _archive.Refs.Size();
UInt64 totalSize = 0;
if(numItems == 0) if(numItems == 0)
return S_OK; return S_OK;
UInt64 totalSize = 0;
UInt32 i; UInt32 i;
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
{ {
@@ -217,12 +185,22 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 currentTotalSize = 0; UInt64 currentTotalSize = 0;
UInt64 currentItemSize; 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) for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
currentItemSize = 0; currentItemSize = 0;
RINOK(extractCallback->SetCompleted(&currentTotalSize));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract; askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kExtract;
@@ -254,45 +232,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if (!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
{
if (testMode) if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL)); RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
streamSpec->Init(currentItemSize); streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, &currentTotalSize, &currentTotalSize);
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(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(res)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ?
} NArchive::NExtract::NOperationResult::kOK:
NArchive::NExtract::NOperationResult::kDataError));
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END

View File

@@ -67,7 +67,7 @@ static const wchar_t *GetOS(Byte osId)
return kUnknownOS; return kUnknownOS;
}; };
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -85,45 +85,10 @@ STATPROPSTG kProperties[] =
}; };
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO
CHandler::CHandler() 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;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
@@ -134,7 +99,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = _items[index]; const CItemEx &item = _items[index];
switch(propID) switch(propID)
{ {
@@ -145,18 +110,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{ {
if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR) if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR)
s.Delete(s.Length() - 1); s.Delete(s.Length() - 1);
propVariant = s; prop = s;
} }
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidSize: case kpidSize:
propVariant = item.Size; prop = item.Size;
break; break;
case kpidPackedSize: case kpidPackedSize:
propVariant = item.PackSize; prop = item.PackSize;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
@@ -177,19 +142,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
else else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
} }
propVariant = utcFileTime; prop = utcFileTime;
break; break;
} }
/* /*
case kpidAttributes: case kpidAttributes:
propVariant = (UInt32)item.Attributes; prop = (UInt32)item.Attributes;
break; break;
case kpidCommented: case kpidCommented:
propVariant = item.IsCommented(); prop = item.IsCommented();
break; break;
*/ */
case kpidCRC: case kpidCRC:
propVariant = (UInt32)item.CRC; prop = (UInt32)item.CRC;
break; break;
case kpidMethod: case kpidMethod:
{ {
@@ -197,14 +162,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
method2[kMethodIdSize] = 0; method2[kMethodIdSize] = 0;
for (int i = 0; i < kMethodIdSize; i++) for (int i = 0; i < kMethodIdSize; i++)
method2[i] = item.Method[i]; method2[i] = item.Method[i];
propVariant = method2; prop = method2;
break; break;
} }
case kpidHostOS: case kpidHostOS:
propVariant = GetOS(item.OsId); prop = GetOS(item.OsId);
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -242,17 +207,17 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
} }
for (;;) for (;;)
{ {
CItemEx itemInfo; CItemEx item;
bool filled; bool filled;
HRESULT result = archive.GetNextItem(filled, itemInfo); HRESULT result = archive.GetNextItem(filled, item);
if (result == S_FALSE) if (result == S_FALSE)
return S_FALSE; return S_FALSE;
if (result != S_OK) if (result != S_OK)
return S_FALSE; return S_FALSE;
if (!filled) if (!filled)
break; break;
_items.Add(itemInfo); _items.Add(item);
archive.Skeep(itemInfo.PackSize); archive.Skeep(item.PackSize);
if (callback != NULL) if (callback != NULL)
{ {
UInt64 numFiles = _items.Size(); UInt64 numFiles = _items.Size();
@@ -298,9 +263,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt32 i; UInt32 i;
for(i = 0; i < numItems; i++) for(i = 0; i < numItems; i++)
{ {
const CItemEx &itemInfo = _items[allFilesMode ? i : indices[i]]; const CItemEx &item = _items[allFilesMode ? i : indices[i]];
totalUnPacked += itemInfo.Size; totalUnPacked += item.Size;
totalPacked += itemInfo.PackSize; totalPacked += item.PackSize;
} }
extractCallback->SetTotal(totalUnPacked); extractCallback->SetTotal(totalUnPacked);
@@ -311,7 +276,17 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CMyComPtr<ICompressCoder> lzhDecoder; CMyComPtr<ICompressCoder> lzhDecoder;
CMyComPtr<ICompressCoder> lzh1Decoder; CMyComPtr<ICompressCoder> lzh1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder; 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, for(i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked) currentTotalPacked += currentItemPacked)
@@ -319,21 +294,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
currentItemUnPacked = 0; currentItemUnPacked = 0;
currentItemPacked = 0; currentItemPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalUnPacked)); lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : askMode = testMode ? NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
const CItemEx &itemInfo = _items[index]; const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
if(itemInfo.IsDirectory()) if(item.IsDirectory())
{ {
// if (!testMode) // if (!testMode)
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
} }
continue; continue;
} }
@@ -342,8 +320,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
currentItemUnPacked = itemInfo.Size; currentItemUnPacked = item.Size;
currentItemPacked = itemInfo.PackSize; currentItemPacked = item.PackSize;
{ {
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
@@ -351,109 +329,58 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
outStreamSpec->Init(realOutStream); outStreamSpec->Init(realOutStream);
realOutStream.Release(); realOutStream.Release();
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
UInt64 pos; UInt64 pos;
_stream->Seek(itemInfo.DataPosition, STREAM_SEEK_SET, &pos); _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
streamSpec->SetStream(_stream); streamSpec->Init(item.PackSize);
streamSpec->Init(itemInfo.PackSize);
HRESULT result = S_OK;
Int32 opRes = NExtract::NOperationResult::kOK;
CLocalProgress *localProgressSpec = new CLocalProgress; if (item.IsCopyMethod())
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalPacked,
&currentTotalUnPacked);
HRESULT result;
if (itemInfo.IsCopyMethod())
{ {
if(!copyCoder) result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
copyCoder = new NCompress::CCopyCoder; if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
try result = S_FALSE;
{
result = copyCoder->Code(inStream, outStream, NULL, NULL, compressProgress);
if (result == S_FALSE)
throw "data error";
if (result != S_OK)
return result;
} }
catch(...) else if (item.IsLh4GroupMethod())
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
}
else if (itemInfo.IsLh4GroupMethod())
{ {
if(!lzhDecoder) if(!lzhDecoder)
{ {
lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder;
lzhDecoder = lzhDecoderSpec; lzhDecoder = lzhDecoderSpec;
} }
try lzhDecoderSpec->SetDictionary(item.GetNumDictBits());
{ result = lzhDecoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
lzhDecoderSpec->SetDictionary(itemInfo.GetNumDictBits());
result = lzhDecoder->Code(inStream, outStream, NULL, &currentItemUnPacked, 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;
}
} }
/* /*
else if (itemInfo.IsLh1GroupMethod()) else if (item.IsLh1GroupMethod())
{ {
if(!lzh1Decoder) if(!lzh1Decoder)
{ {
lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder; lzh1DecoderSpec = new NCompress::NLzh1::NDecoder::CCoder;
lzh1Decoder = lzh1DecoderSpec; lzh1Decoder = lzh1DecoderSpec;
} }
try lzh1DecoderSpec->SetDictionary(item.GetNumDictBits());
{ result = lzh1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
lzh1DecoderSpec->SetDictionary(itemInfo.GetNumDictBits());
result = lzh1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, 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;
}
} }
*/ */
else else
{ opRes = NExtract::NOperationResult::kUnSupportedMethod;
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
bool crcOK = (outStreamSpec->GetCRC() == itemInfo.CRC); if (opRes == NExtract::NOperationResult::kOK)
outStream.Release(); {
if(crcOK) if (result == S_FALSE)
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)) opRes = NExtract::NOperationResult::kDataError;
else else
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) {
RINOK(result);
if (outStreamSpec->GetCRC() != item.CRC)
opRes = NExtract::NOperationResult::kCRCError;
}
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
} }
} }
return S_OK; return S_OK;

View File

@@ -31,7 +31,7 @@ static const wchar_t *kMethods[] =
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -42,43 +42,44 @@ STATPROPSTG kProperties[] =
{ NULL, kpidSolid, VT_BOOL} { 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; 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) STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)
{
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 */)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
Close(); Close();
@@ -142,6 +143,24 @@ static UString GetStringForSizeValue(UInt32 value)
return result; 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) bool CHandler::GetUncompressedSize(int index, UInt32 &size)
{ {
size = 0; size = 0;
@@ -185,24 +204,24 @@ bool CHandler::GetCompressedSize(int index, UInt32 &size)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
#ifdef NSIS_SCRIPT #ifdef NSIS_SCRIPT
if (index >= (UInt32)_archive.Items.Size()) if (index >= (UInt32)_archive.Items.Size())
{ {
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
propVariant = L"[NSIS].nsi"; prop = L"[NSIS].nsi";
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = false; prop = false;
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
propVariant = (UInt64)_archive.Script.Length(); prop = (UInt64)_archive.Script.Length();
break; break;
case kpidSolid: case kpidSolid:
propVariant = false; prop = false;
break; break;
} }
} }
@@ -215,57 +234,44 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath: case kpidPath:
{ {
const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP)); const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP));
propVariant = (const wchar_t *)s; prop = (const wchar_t *)s;
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = false; prop = false;
break; break;
case kpidSize: case kpidSize:
{ {
UInt32 size; UInt32 size;
if (GetUncompressedSize(index, size)) if (GetUncompressedSize(index, size))
propVariant = (UInt64)size; prop = (UInt64)size;
break; break;
} }
case kpidPackedSize: case kpidPackedSize:
{ {
UInt32 size; UInt32 size;
if (GetCompressedSize(index, size)) if (GetCompressedSize(index, size))
propVariant = (UInt64)size; prop = (UInt64)size;
break; break;
} }
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
if (item.DateTime.dwHighDateTime > 0x01000000 && if (item.DateTime.dwHighDateTime > 0x01000000 &&
item.DateTime.dwHighDateTime < 0xFF000000) item.DateTime.dwHighDateTime < 0xFF000000)
propVariant = item.DateTime; prop = item.DateTime;
break; break;
} }
case kpidMethod: case kpidMethod:
{ {
NMethodType::EEnum methodIndex = _archive.Method; prop = GetMethod(item.UseFilter, item.DictionarySize);
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;
break; break;
} }
case kpidSolid: case kpidSolid:
propVariant = _archive.IsSolid; prop = _archive.IsSolid;
break; break;
} }
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -478,7 +484,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
} }
} }
} }
if (!testMode)
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(dataError ? RINOK(extractCallback->SetOperationResult(dataError ?
NArchive::NExtract::NOperationResult::kDataError : NArchive::NExtract::NOperationResult::kDataError :

View File

@@ -26,6 +26,7 @@ class CHandler:
bool GetUncompressedSize(int index, UInt32 &size); bool GetUncompressedSize(int index, UInt32 &size);
bool GetCompressedSize(int index, UInt32 &size); bool GetCompressedSize(int index, UInt32 &size);
UString GetMethod(bool useItemFilter, UInt32 dictionary) const;
public: public:
MY_QUERYINTERFACE_BEGIN2(IInArchive) MY_QUERYINTERFACE_BEGIN2(IInArchive)
QUERY_ENTRY_ISetCompressCodecsInfo QUERY_ENTRY_ISetCompressCodecsInfo

View File

@@ -905,10 +905,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{ {
Items.Sort(CompareItems, 0); Items.Sort(CompareItems, 0);
int i; int i;
if (IsSolid) // if (IsSolid)
for (i = 0; i + 1 < Items.Size();) 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); Items.Delete(i + 1);
else else
i++; i++;

View File

@@ -25,49 +25,14 @@ using namespace NWindows;
namespace NArchive { namespace NArchive {
namespace NRpm { namespace NRpm {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
// { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL},
{ NULL, kpidSize, VT_UI8}, { NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8} { NULL, kpidPackedSize, VT_UI8}
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
@@ -106,27 +71,16 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop;
NWindows::NCOM::CPropVariant propVariant;
switch(propID) switch(propID)
{ {
/*
case kpidPath:
propVariant = (const wchar_t *)L"a.cpio.gz";
break;
*/
case kpidIsFolder:
propVariant = false;
break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
propVariant = m_Size; prop = m_Size;
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END
} }
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, 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->SetTotal(m_Size));
RINOK(extractCallback->SetCompleted(&currentTotalSize)); RINOK(extractCallback->SetCompleted(&currentTotalSize));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode = testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
Int32 index = 0; Int32 index = 0;
@@ -171,23 +125,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder; CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(extractCallback, false); lps->Init(extractCallback, false);
try
{
RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress)); RINOK(copyCoder->Code(m_InStream, realOutStream, NULL, NULL, progress));
}
catch(...)
{
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
return S_OK;
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
return S_OK;
COM_TRY_END COM_TRY_END
} }

View File

@@ -42,12 +42,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown"; static const wchar_t *kUnknownOS = L"Unknown";
enum // PropID STATPROPSTG kProps[] =
{
kpidUnPackVersion = kpidUserDefined
};
STATPROPSTG kProperties[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -58,7 +53,6 @@ STATPROPSTG kProperties[] =
{ NULL, kpidLastAccessTime, VT_FILETIME}, { NULL, kpidLastAccessTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4}, { NULL, kpidAttributes, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL}, { NULL, kpidEncrypted, VT_BOOL},
{ NULL, kpidSolid, VT_BOOL}, { NULL, kpidSolid, VT_BOOL},
{ NULL, kpidCommented, VT_BOOL}, { NULL, kpidCommented, VT_BOOL},
@@ -66,17 +60,23 @@ STATPROPSTG kProperties[] =
{ NULL, kpidSplitAfter, VT_BOOL}, { NULL, kpidSplitAfter, VT_BOOL},
{ NULL, kpidCRC, VT_UI4}, { NULL, kpidCRC, VT_UI4},
{ NULL, kpidHostOS, VT_BSTR}, { NULL, kpidHostOS, VT_BSTR},
{ NULL, kpidMethod, VT_BSTR} { NULL, kpidMethod, VT_BSTR},
// { NULL, kpidDictionarySize, VT_UI4}, { NULL, kpidUnpackVer, VT_UI1}
// { L"UnPack Version", kpidUnPackVersion, VT_UI1}
}; };
STATPROPSTG kArchiveProperties[] = STATPROPSTG kArcProps[] =
{ {
{ NULL, kpidSolid, VT_BOOL}, { 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 UInt64 CHandler::GetPackSize(int refIndex) const
{ {
const CRefItem &refItem = _refItems[refIndex]; const CRefItem &refItem = _refItems[refIndex];
@@ -88,56 +88,29 @@ UInt64 CHandler::GetPackSize(int refIndex) const
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN // COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
case kpidSolid: case kpidSolid: prop = _archiveInfo.IsSolid(); break;
propVariant = _archiveInfo.IsSolid(); case kpidEncrypted: prop = _archiveInfo.IsEncrypted(); break;
break; case kpidIsVolume: prop = _archiveInfo.IsVolume(); break;
case kpidCommented: case kpidNumBlocks:
propVariant = _archiveInfo.IsCommented(); {
UInt32 numBlocks = 0;
for (int i = 0; i < _refItems.Size(); i++)
if (!IsSolid(i))
numBlocks++;
prop = (UInt32)numBlocks;
break; break;
} }
propVariant.Detach(value); case kpidNumVolumes: prop = (UInt32)(_archives.Size() - 1);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) // case kpidCommented: prop = _archiveInfo.IsCommented(); break;
{
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK;
} }
prop.Detach(value);
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;
return S_OK; return S_OK;
// COM_TRY_END
} }
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
@@ -160,10 +133,23 @@ static bool RarTimeToFileTime(const CRarTime &rarTime, FILETIME &result)
return true; 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) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CRefItem &refItem = _refItems[index]; const CRefItem &refItem = _refItems[index];
const CItemEx &item = _items[refItem.ItemIndex]; const CItemEx &item = _items[refItem.ItemIndex];
switch(propID) switch(propID)
@@ -175,102 +161,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
u = item.UnicodeName; u = item.UnicodeName;
else else
u = MultiByteToUnicodeString(item.Name, CP_OEMCP); u = MultiByteToUnicodeString(item.Name, CP_OEMCP);
propVariant = (const wchar_t *)NItemName::WinNameToOSName(u); prop = (const wchar_t *)NItemName::WinNameToOSName(u);
break; break;
} }
case kpidIsFolder: case kpidIsFolder: prop = item.IsDirectory(); break;
propVariant = item.IsDirectory(); case kpidSize: prop = item.UnPackSize; break;
break; case kpidPackedSize: prop = GetPackSize(index); break;
case kpidSize: case kpidLastWriteTime: RarTimeToProp(item.LastWriteTime, prop);
propVariant = item.UnPackSize; case kpidCreationTime: if (item.IsCreationTimeDefined) RarTimeToProp(item.CreationTime, prop); break;
break; case kpidLastAccessTime: if (item.IsLastAccessTimeDefined) RarTimeToProp(item.LastAccessTime, prop); break;
case kpidPackedSize: case kpidAttributes: prop = item.GetWinAttributes(); break;
{ case kpidEncrypted: prop = item.IsEncrypted(); break;
propVariant = GetPackSize(index); case kpidSolid: prop = IsSolid(index); break;
break; case kpidCommented: prop = item.IsCommented(); break;
} case kpidSplitBefore: prop = item.IsSplitBefore(); break;
case kpidLastWriteTime: case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break;
{
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 kpidCRC: case kpidCRC:
{ {
const CItemEx &lastItem = const CItemEx &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
_items[refItem.ItemIndex + refItem.NumItems - 1]; prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);
if (lastItem.IsSplitAfter())
propVariant = item.FileCRC;
else
propVariant = lastItem.FileCRC;
break; break;
} }
case kpidUnPackVersion: case kpidUnpackVer: prop = item.UnPackVersion; break;
propVariant = item.UnPackVersion;
break;
case kpidMethod: case kpidMethod:
{ {
UString method; UString method;
@@ -293,15 +205,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
ConvertUInt64ToString(item.Method, temp); ConvertUInt64ToString(item.Method, temp);
method += temp; method += temp;
} }
propVariant = method; prop = method;
break; break;
} }
case kpidHostOS: case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
propVariant = (item.HostOS < kNumHostOSes) ?
(kHostOS[item.HostOS]) : kUnknownOS;
break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -325,8 +234,12 @@ public:
if (dotPos >= 0) if (dotPos >= 0)
{ {
UString ext = name.Mid(dotPos + 1); UString ext = name.Mid(dotPos + 1);
if (ext.CompareNoCase(L"RAR")==0 || if (ext.CompareNoCase(L"rar") == 0)
ext.CompareNoCase(L"EXE") == 0) {
_afterPart = name.Mid(dotPos);
basePart = name.Left(dotPos);
}
else if (ext.CompareNoCase(L"exe") == 0)
{ {
_afterPart = L".rar"; _afterPart = L".rar";
basePart = name.Left(dotPos); basePart = name.Left(dotPos);
@@ -338,11 +251,11 @@ public:
_afterPart.Empty(); _afterPart.Empty();
_unchangedPart = basePart + UString(L"."); _unchangedPart = basePart + UString(L".");
_changedPart = L"r00"; _changedPart = L"r00";
return true;; return true;
} }
int numLetters = 1; int numLetters = 1;
if (basePart.Right(numLetters) == L"1") if (basePart.Right(numLetters) == L"1" || basePart.Right(numLetters) == L"0")
{ {
while (numLetters < basePart.Length()) while (numLetters < basePart.Length())
{ {
@@ -427,11 +340,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
break; break;
UString baseName; UString baseName;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (propVariant.vt != VT_BSTR) if (prop.vt != VT_BSTR)
break; break;
baseName = propVariant.bstrVal; baseName = prop.bstrVal;
} }
seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName()); seqName.InitName(baseName, _archiveInfo.HaveNewVolumeName());
} }
@@ -572,8 +485,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CObjectVector<CMethodItem> methodItems; CObjectVector<CMethodItem> methodItems;
NCompress::CCopyCoder *copyCoderSpec = NULL; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CFilterCoder *filterStreamSpec = new CFilterCoder; CFilterCoder *filterStreamSpec = new CFilterCoder;
CMyComPtr<ISequentialInStream> filterStream = filterStreamSpec; CMyComPtr<ISequentialInStream> filterStream = filterStreamSpec;
@@ -586,18 +499,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CFolderInStream *folderInStreamSpec = NULL; CFolderInStream *folderInStreamSpec = NULL;
CMyComPtr<ISequentialInStream> folderInStream; CMyComPtr<ISequentialInStream> folderInStream;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
bool solidStart = true; bool solidStart = true;
for(int i = 0; i < importantIndexes.Size(); i++, for(int i = 0; i < importantIndexes.Size(); i++,
currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalUnPacked += currentUnPackSize,
currentImportantTotalPacked += currentPackSize) currentImportantTotalPacked += currentPackSize)
{ {
RINOK(extractCallback->SetCompleted( lps->InSize = currentImportantTotalPacked;
&currentImportantTotalUnPacked)); lps->OutSize = currentImportantTotalUnPacked;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode;
if(extractStatuses[i]) if(extractStatuses[i])
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : askMode = testMode ?
NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
else else
askMode = NArchive::NExtract::NAskMode::kSkip; askMode = NArchive::NExtract::NAskMode::kSkip;
@@ -648,9 +567,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
outStreamSpec->Init(); outStreamSpec->Init();
realOutStream.Release(); realOutStream.Release();
UInt64 packedPos = currentImportantTotalPacked;
UInt64 unpackedPos = currentImportantTotalUnPacked;
/* /*
for (int partIndex = 0; partIndex < 1; partIndex++) for (int partIndex = 0; partIndex < 1; partIndex++)
{ {
@@ -672,18 +588,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
folderInStreamSpec->Init(&_archives, &_items, refItem); 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; UInt64 packSize = currentPackSize;
// packedPos += item.PackSize; // packedPos += item.PackSize;
@@ -773,11 +677,6 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
{ {
case '0': case '0':
{ {
if(copyCoderSpec == NULL)
{
copyCoderSpec = new NCompress::CCopyCoder;
copyCoder = copyCoderSpec;
}
commonCoder = copyCoder; commonCoder = copyCoder;
break; break;
} }
@@ -850,8 +749,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue; continue;
} }
HRESULT result = commonCoder->Code(inStream, outStream, HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.UnPackSize, progress);
&packSize, &item.UnPackSize, compressProgress);
if (item.IsEncrypted()) if (item.IsEncrypted())
filterStreamSpec->ReleaseInStream(); filterStreamSpec->ReleaseInStream();
if (result == S_FALSE) if (result == S_FALSE)

View File

@@ -439,7 +439,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa
const UInt32 kSaltSize = 8; const UInt32 kSaltSize = 8;
Byte salt[kSaltSize]; Byte salt[kSaltSize];
if(!ReadBytesAndTestSize(salt, kSaltSize)) if(!ReadBytesAndTestSize(salt, kSaltSize))
return false; return S_FALSE;
m_Position += kSaltSize; m_Position += kSaltSize;
RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize)) RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize))
// Password // Password

View File

@@ -33,9 +33,9 @@ class CInArchiveInfo
{ {
public: public:
UInt64 StartPosition; UInt64 StartPosition;
WORD Flags; UInt16 Flags;
UInt64 CommentPosition; UInt64 CommentPosition;
WORD CommentSize; UInt16 CommentSize;
bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; } bool IsSolid() const { return (Flags & NHeader::NArchive::kSolid) != 0; }
bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; }
bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; }

View File

@@ -8,6 +8,6 @@
static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; } static IInArchive *CreateArc() { return new NArchive::NRar::CHandler; }
static CArcInfo g_ArcInfo = 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) REGISTER_ARC(Rar)

View File

@@ -23,7 +23,7 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NSplit { namespace NSplit {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
// { NULL, kpidIsFolder, VT_BOOL}, // { NULL, kpidIsFolder, VT_BOOL},
@@ -31,41 +31,8 @@ STATPROPSTG kProperties[] =
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8},
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
class CSeqName class CSeqName
{ {
@@ -158,11 +125,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
return S_FALSE; return S_FALSE;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (propVariant.vt != VT_BSTR) if (prop.vt != VT_BSTR)
return S_FALSE; return S_FALSE;
_name = propVariant.bstrVal; _name = prop.bstrVal;
} }
int dotPos = _name.ReverseFind('.'); int dotPos = _name.ReverseFind('.');
@@ -219,11 +186,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
_totalSize = 0; _totalSize = 0;
UInt64 size; UInt64 size;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = propVariant.uhVal.QuadPart; size = prop.uhVal.QuadPart;
} }
_totalSize += size; _totalSize += size;
_sizes.Add(size); _sizes.Add(size);
@@ -247,11 +214,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
if (!stream) if (!stream)
break; break;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidSize, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = propVariant.uhVal.QuadPart; size = prop.uhVal.QuadPart;
} }
_totalSize += size; _totalSize += size;
_sizes.Add(size); _sizes.Add(size);
@@ -288,25 +255,22 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop;
NWindows::NCOM::CPropVariant propVariant;
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
propVariant = _subName; prop = _subName;
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = false; prop = false;
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
propVariant = _totalSize; prop = _totalSize;
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END
} }
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, 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)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
return S_OK; return S_OK;
} }
// currentItemSize = itemInfo.Size;
if (!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
{
return S_OK; return S_OK;
}
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for (int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize) for (int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize)
{ {
// CMyComPtr<ISequentialInStream> inStream; lps->InSize = lps->OutSize = currentTotalSize;
// RINOK(volumeExtractCallback->GetInStream(_names[i], &inStream)); RINOK(lps->SetCur());
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalSize, &currentTotalSize);
IInStream *inStream = _streams[i]; IInStream *inStream = _streams[i];
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
try RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
return S_OK;;
}
currentItemSize = copyCoderSpec->TotalSize; currentItemSize = copyCoderSpec->TotalSize;
} }
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); return extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK);
return S_OK;
COM_TRY_END COM_TRY_END
} }

View File

@@ -48,30 +48,30 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (newProperties != 0) if (newProperties != 0)
{ {
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &propVariant)); RINOK(updateCallback->GetProperty(fileIndex, kpidIsFolder, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
{ {
} }
else if (propVariant.vt != VT_BOOL) else if (prop.vt != VT_BOOL)
return E_INVALIDARG; return E_INVALIDARG;
else else
{ {
if (propVariant.boolVal != VARIANT_FALSE) if (prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG; return E_INVALIDARG;
} }
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &propVariant)); RINOK(updateCallback->GetProperty(fileIndex, kpidIsAnti, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
{ {
} }
else if (propVariant.vt != VT_BOOL) else if (prop.vt != VT_BOOL)
return E_INVALIDARG; return E_INVALIDARG;
else else
{ {
if (propVariant.boolVal != VARIANT_FALSE) if (prop.boolVal != VARIANT_FALSE)
return E_INVALIDARG; return E_INVALIDARG;
} }
} }
@@ -80,11 +80,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool thereIsCopyData = false; bool thereIsCopyData = false;
if (newData != 0) if (newData != 0)
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(fileIndex, kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
newSize = propVariant.uhVal.QuadPart; newSize = prop.uhVal.QuadPart;
} }
else else
thereIsCopyData = true; thereIsCopyData = true;

View File

@@ -1,4 +1,4 @@
// Tar/Handler.cpp / Tar/Handler.cpp
#include "StdAfx.h" #include "StdAfx.h"
@@ -15,6 +15,7 @@
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h" #include "../../Common/LimitedStreams.h"
#include "../../Compress/Copy/CopyCoder.h" #include "../../Compress/Copy/CopyCoder.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
@@ -25,7 +26,7 @@ using namespace NTime;
namespace NArchive { namespace NArchive {
namespace NTar { namespace NTar {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -36,41 +37,16 @@ STATPROPSTG kProperties[] =
{ NULL, kpidGroup, VT_BSTR}, { 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, STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 * /* maxCheckStartPosition */, const UInt64 * /* maxCheckStartPosition */,
@@ -120,11 +96,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
if (!openVolumeCallback) if (!openVolumeCallback)
return S_FALSE; return S_FALSE;
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (propVariant.vt != VT_BSTR) if (prop.vt != VT_BSTR)
return S_FALSE; return S_FALSE;
UString baseName = propVariant.bstrVal; UString baseName = prop.bstrVal;
baseName = baseName.Right(4); baseName = baseName.Right(4);
if (baseName.CompareNoCase(L".tar") != 0) if (baseName.CompareNoCase(L".tar") != 0)
return S_FALSE; return S_FALSE;
@@ -157,45 +133,45 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const NArchive::NTar::CItemEx &item = _items[index]; const CItemEx &item = _items[index];
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
propVariant = (const wchar_t *)NItemName::GetOSName2( prop = (const wchar_t *)NItemName::GetOSName2(
MultiByteToUnicodeString(item.Name, CP_OEMCP)); MultiByteToUnicodeString(item.Name, CP_OEMCP));
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidSize: case kpidSize:
case kpidPackedSize: case kpidPackedSize:
propVariant = (UInt64)item.Size; prop = (UInt64)item.Size;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
FILETIME utcFileTime; FILETIME utcFileTime;
if (item.ModificationTime != 0) if (item.ModificationTime != 0)
NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime); NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
else else
{ {
utcFileTime.dwLowDateTime = 0; utcFileTime.dwLowDateTime = 0;
utcFileTime.dwHighDateTime = 0; utcFileTime.dwHighDateTime = 0;
} }
propVariant = utcFileTime; prop = utcFileTime;
break; break;
} }
case kpidUser: case kpidUser:
propVariant = (const wchar_t *) prop = (const wchar_t *)
MultiByteToUnicodeString(item.UserName, CP_OEMCP); MultiByteToUnicodeString(item.UserName, CP_OEMCP);
break; break;
case kpidGroup: case kpidGroup:
propVariant = (const wchar_t *) prop = (const wchar_t *)
MultiByteToUnicodeString(item.GroupName, CP_OEMCP); MultiByteToUnicodeString(item.GroupName, CP_OEMCP);
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -208,9 +184,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
bool allFilesMode = (numItems == UInt32(-1)); bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode) if (allFilesMode)
numItems = _items.Size(); numItems = _items.Size();
UInt64 totalSize = 0;
if (numItems == 0) if (numItems == 0)
return S_OK; return S_OK;
UInt64 totalSize = 0;
UInt32 i; UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
totalSize += _items[allFilesMode ? i : indices[i]].Size; totalSize += _items[allFilesMode ? i : indices[i]].Size;
@@ -219,22 +195,29 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 currentTotalSize = 0; UInt64 currentTotalSize = 0;
UInt64 currentItemSize; 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) for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&currentTotalSize)); lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode = testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NArchive::NExtract::NAskMode::kExtract;
Int32 index = allFilesMode ? i : indices[i]; Int32 index = allFilesMode ? i : indices[i];
const CItemEx &item = _items[index]; const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
currentItemSize = item.Size; currentItemSize = item.Size;
if (item.IsDirectory()) if (item.IsDirectory())
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
@@ -242,52 +225,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue; continue;
} }
if (!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
{
continue; continue;
}
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
{
if (testMode) if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL)); RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
streamSpec->Init(item.Size); streamSpec->Init(item.Size);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalSize, &currentTotalSize);
if(!copyCoder)
{
copyCoder = new NCompress::CCopyCoder;
}
try
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
continue; NArchive::NExtract::NOperationResult::kOK:
} NArchive::NExtract::NOperationResult::kDataError));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END

View File

@@ -53,42 +53,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool isDirectoryStatusDefined; bool isDirectoryStatusDefined;
UInt32 attributes; UInt32 attributes;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidAttributes, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
attributes = 0; attributes = 0;
else if (propVariant.vt != VT_UI4) else if (prop.vt != VT_UI4)
return E_INVALIDARG; return E_INVALIDARG;
else else
attributes = propVariant.ulVal; attributes = prop.ulVal;
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &prop));
if (propVariant.vt != VT_FILETIME) if (prop.vt != VT_FILETIME)
return E_INVALIDARG; return E_INVALIDARG;
utcTime = propVariant.filetime; utcTime = prop.filetime;
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
name.Empty(); name.Empty();
else if (propVariant.vt != VT_BSTR) else if (prop.vt != VT_BSTR)
return E_INVALIDARG; return E_INVALIDARG;
else else
name = propVariant.bstrVal; name = prop.bstrVal;
} }
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidIsFolder, &prop));
if (propVariant.vt == VT_EMPTY) if (prop.vt == VT_EMPTY)
isDirectoryStatusDefined = false; isDirectoryStatusDefined = false;
else if (propVariant.vt != VT_BOOL) else if (prop.vt != VT_BOOL)
return E_INVALIDARG; return E_INVALIDARG;
else else
{ {
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE); updateItem.IsDirectory = (prop.boolVal != VARIANT_FALSE);
isDirectoryStatusDefined = true; isDirectoryStatusDefined = true;
} }
} }
@@ -109,11 +109,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{ {
UInt64 size; UInt64 size;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant)); RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
if (propVariant.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = propVariant.uhVal.QuadPart; size = prop.uhVal.QuadPart;
} }
updateItem.Size = size; updateItem.Size = size;
} }

View File

@@ -13,23 +13,9 @@
#include "TarOut.h" #include "TarOut.h"
#include "TarUpdate.h" #include "TarUpdate.h"
static const UInt64 kOneItemComplexity = 512;
namespace NArchive { namespace NArchive {
namespace NTar { 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, HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
const CObjectVector<NArchive::NTar::CItemEx> &inputItems, const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
const CObjectVector<CUpdateItemInfo> &updateItems, const CObjectVector<CUpdateItemInfo> &updateItems,
@@ -48,25 +34,27 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
complexity += updateItem.Size; complexity += updateItem.Size;
else else
complexity += inputItems[updateItem.IndexInArchive].GetFullSize(); complexity += inputItems[updateItem.IndexInArchive].GetFullSize();
complexity += kOneItemComplexity;
} }
RINOK(updateCallback->SetTotal(complexity)); 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; complexity = 0;
for(i = 0; i < updateItems.Size(); i++) for(i = 0; i < updateItems.Size(); i++)
{ {
RINOK(updateCallback->SetCompleted(&complexity)); lps->InSize = lps->OutSize = complexity;
RINOK(lps->SetCur());
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);
const CUpdateItemInfo &updateItem = updateItems[i]; const CUpdateItemInfo &updateItem = updateItems[i];
CItem item; CItem item;
@@ -118,45 +106,40 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
RINOK(outArchive.WriteHeader(item)); RINOK(outArchive.WriteHeader(item));
if (!updateItem.IsDirectory) if (!updateItem.IsDirectory)
{ {
UInt64 totalSize; RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize)); if (copyCoderSpec->TotalSize != item.Size)
if (totalSize != item.Size)
return E_FAIL; return E_FAIL;
RINOK(outArchive.FillDataResidual(item.Size)); RINOK(outArchive.FillDataResidual(item.Size));
} }
} }
complexity += updateItem.Size; complexity += updateItem.Size;
RINOK(updateCallback->SetOperationResult( RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
NArchive::NUpdate::NOperationResult::kOK));
} }
else else
{ {
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive]; const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
UInt64 size;
if (updateItem.NewProperties) if (updateItem.NewProperties)
{ {
RINOK(outArchive.WriteHeader(item)); RINOK(outArchive.WriteHeader(item));
RINOK(inStream->Seek(existItemInfo.GetDataPosition(), RINOK(inStream->Seek(existItemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
STREAM_SEEK_SET, NULL)); size = existItemInfo.Size;
streamSpec->SetStream(inStream);
streamSpec->Init(existItemInfo.Size);
} }
else else
{ {
RINOK(inStream->Seek(existItemInfo.HeaderPosition, RINOK(inStream->Seek(existItemInfo.HeaderPosition, STREAM_SEEK_SET, NULL));
STREAM_SEEK_SET, NULL)); size = existItemInfo.GetFullSize();
streamSpec->SetStream(inStream);
streamSpec->Init(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)); RINOK(outArchive.FillDataResidual(existItemInfo.Size));
complexity += existItemInfo.GetFullSize(); complexity += size;
} }
complexity += kOneItemComplexity;
} }
return outArchive.WriteFinishHeader(); return outArchive.WriteFinishHeader();
} }
}} }}

View File

@@ -20,18 +20,7 @@ namespace NWim {
#define WIM_DETAILS #define WIM_DETAILS
#ifdef WIM_DETAILS STATPROPSTG kProps[] =
enum
{
kpidVolume = kpidUserDefined,
kpidOffset,
kpidLinks
};
#endif
STATPROPSTG kProperties[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -44,59 +33,63 @@ STATPROPSTG kProperties[] =
{ NULL, kpidLastWriteTime, VT_FILETIME} { NULL, kpidLastWriteTime, VT_FILETIME}
#ifdef WIM_DETAILS #ifdef WIM_DETAILS
, { L"Volume", kpidVolume, VT_UI4} , { NULL, kpidVolume, VT_UI4}
, { L"Offset", kpidOffset, VT_UI8} , { NULL, kpidOffset, VT_UI8}
, { L"Links", kpidLinks, VT_UI4} , { NULL, kpidLinks, VT_UI4}
#endif #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 *kStreamsNamePrefix = L"Files" WSTRING_PATH_SEPARATOR;
static const wchar_t *kMethodLZX = L"LZX"; static const wchar_t *kMethodLZX = L"LZX";
static const wchar_t *kMethodCopy = L"Copy"; static const wchar_t *kMethodCopy = L"Copy";
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps
value->vt = VT_EMPTY;
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]); COM_TRY_BEGIN
return S_OK; 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;
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, case kpidVolume:
BSTR *name, PROPID *propID, VARTYPE *varType) if (m_Xmls.Size() > 0)
{ {
if(index >= sizeof(kProperties) / sizeof(kProperties[0])) UInt16 volIndex = m_Xmls[0].VolIndex;
return E_INVALIDARG; if (volIndex < m_Volumes.Size())
const STATPROPSTG &srcItem = kProperties[index]; prop = m_Volumes[volIndex].Header.PartNumber;
*propID = srcItem.propid;
*varType = srcItem.vt;
if (srcItem.lpwstrName == 0)
*name = 0;
else
*name = ::SysAllocString(srcItem.lpwstrName);
return S_OK;
} }
break;
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1);
{
*numProperties = 0;
return S_OK;
} }
prop.Detach(value);
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, return S_OK;
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) COM_TRY_END
{
return E_INVALIDARG;
} }
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
if (index < (UInt32)m_Database.Items.Size()) if (index < (UInt32)m_Database.Items.Size())
{ {
const CItem &item = m_Database.Items[index]; const CItem &item = m_Database.Items[index];
@@ -108,7 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
case kpidPath: case kpidPath:
if (item.HasMetadata) if (item.HasMetadata)
propVariant = item.Name; prop = item.Name;
else else
{ {
wchar_t sz[32]; wchar_t sz[32];
@@ -117,62 +110,62 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
while (s.Length() < m_NameLenForStreams) while (s.Length() < m_NameLenForStreams)
s = L'0' + s; s = L'0' + s;
s = UString(kStreamsNamePrefix) + s; s = UString(kStreamsNamePrefix) + s;
propVariant = s; prop = s;
break; break;
} }
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidAttributes: case kpidAttributes:
if (item.HasMetadata) if (item.HasMetadata)
propVariant = item.Attributes; prop = item.Attributes;
break; break;
case kpidCreationTime: case kpidCreationTime:
if (item.HasMetadata) if (item.HasMetadata)
propVariant = item.CreationTime; prop = item.CreationTime;
break; break;
case kpidLastAccessTime: case kpidLastAccessTime:
if (item.HasMetadata) if (item.HasMetadata)
propVariant = item.LastAccessTime; prop = item.LastAccessTime;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
if (item.HasMetadata) if (item.HasMetadata)
propVariant = item.LastWriteTime; prop = item.LastWriteTime;
break; break;
case kpidPackedSize: case kpidPackedSize:
if (si) if (si)
propVariant = si->Resource.PackSize; prop = si->Resource.PackSize;
else else
propVariant = (UInt64)0; prop = (UInt64)0;
break; break;
case kpidSize: case kpidSize:
if (si) if (si)
propVariant = si->Resource.UnpackSize; prop = si->Resource.UnpackSize;
else else
propVariant = (UInt64)0; prop = (UInt64)0;
break; break;
case kpidMethod: case kpidMethod:
if (si) if (si)
if (si->Resource.IsCompressed()) if (si->Resource.IsCompressed())
propVariant = kMethodLZX; prop = kMethodLZX;
else else
propVariant = kMethodCopy; prop = kMethodCopy;
break; break;
#ifdef WIM_DETAILS #ifdef WIM_DETAILS
case kpidVolume: case kpidVolume:
if (si) if (si)
propVariant = (UInt32)si->PartNumber; prop = (UInt32)si->PartNumber;
break; break;
case kpidOffset: case kpidOffset:
if (si) if (si)
propVariant = (UInt64)si->Resource.Offset; prop = (UInt64)si->Resource.Offset;
break; break;
case kpidLinks: case kpidLinks:
if (si) if (si)
propVariant = (UInt32)si->RefCount; prop = (UInt32)si->RefCount;
else else
propVariant = (UInt64)0; prop = (UInt64)0;
break; break;
#endif #endif
} }
@@ -188,23 +181,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
wchar_t sz[32]; wchar_t sz[32];
ConvertUInt64ToString(m_Xmls[index].VolIndex, sz); ConvertUInt64ToString(m_Xmls[index].VolIndex, sz);
UString s = (UString)sz + L".xml"; UString s = (UString)sz + L".xml";
propVariant = s; prop = s;
break; break;
} }
case kpidIsFolder: case kpidIsFolder:
propVariant = false; prop = false;
break; break;
case kpidPackedSize: case kpidPackedSize:
case kpidSize: case kpidSize:
propVariant = (UInt64)m_Xmls[index].Data.GetCapacity(); prop = (UInt64)m_Xmls[index].Data.GetCapacity();
break; break;
case kpidMethod: case kpidMethod:
propVariant = L"Copy"; prop = L"Copy";
break; break;
} }
} }
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -317,11 +310,11 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
break; break;
numVolumes = header.NumParts; numVolumes = header.NumParts;
{ {
NCOM::CPropVariant propVariant; NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant)); RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (propVariant.vt != VT_BSTR) if (prop.vt != VT_BSTR)
break; 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)); RINOK(extractCallback->SetTotal(totalSize));
UInt64 currentTotalSize = 0; UInt64 currentTotalPacked = 0;
UInt64 currentItemSize = 0; UInt64 currentTotalUnPacked = 0;
UInt64 currentItemUnPacked, currentItemPacked;
int prevSuccessStreamIndex = -1; int prevSuccessStreamIndex = -1;
CUnpacker unpacker; CUnpacker unpacker;
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(extractCallback, false); lps->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; for (i = 0; i < numItems; currentTotalUnPacked += currentItemUnPacked,
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; currentTotalPacked += currentItemPacked)
for (i = 0; i < numItems; currentTotalSize += currentItemSize)
{ {
currentItemSize = 0; currentItemUnPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalSize)); currentItemPacked = 0;
lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
UInt32 index = allFilesMode ? i : indices[i]; UInt32 index = allFilesMode ? i : indices[i];
i++; i++;
Int32 askMode = testMode ? Int32 askMode = testMode ?
NArchive::NExtract::NAskMode::kTest : NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -413,13 +410,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
const CByteBuffer &data = m_Xmls[index - (UInt32)m_Database.Items.Size()].Data; const CByteBuffer &data = m_Xmls[index - (UInt32)m_Database.Items.Size()].Data;
currentItemSize = data.GetCapacity(); currentItemUnPacked = data.GetCapacity();
if (realOutStream) if (realOutStream)
{ {
RINOK(WriteStream(realOutStream, (const Byte *)data, (UInt32)data.GetCapacity(), NULL)); RINOK(WriteStream(realOutStream, (const Byte *)data, (UInt32)data.GetCapacity(), NULL));
realOutStream.Release(); realOutStream.Release();
} }
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
continue; continue;
} }
@@ -432,32 +429,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(item.HasStream() ? RINOK(extractCallback->SetOperationResult(item.HasStream() ?
NArchive::NExtract::NOperationResult::kDataError : NExtract::NOperationResult::kDataError :
NArchive::NExtract::NOperationResult::kOK)); NExtract::NOperationResult::kOK));
continue; continue;
} }
const CStreamInfo &si = m_Database.Streams[streamIndex]; const CStreamInfo &si = m_Database.Streams[streamIndex];
currentItemSize = si.Resource.UnpackSize; currentItemUnPacked = si.Resource.UnpackSize;
currentItemPacked = si.Resource.PackSize;
if(!testMode && (!realOutStream)) if(!testMode && (!realOutStream))
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
Int32 opRes = NArchive::NExtract::NOperationResult::kOK; Int32 opRes = NExtract::NOperationResult::kOK;
if (streamIndex != prevSuccessStreamIndex || realOutStream) if (streamIndex != prevSuccessStreamIndex || realOutStream)
{ {
Byte digest[20]; Byte digest[20];
localCompressProgressSpec->Init(progress, &currentTotalSize, &currentTotalSize); HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, progress, digest);
HRESULT res = unpacker.Unpack(m_Volumes[si.PartNumber].Stream, si.Resource, realOutStream, compressProgress, digest);
if (res == S_OK) if (res == S_OK)
{ {
if (memcmp(digest, si.Hash, kHashSize) == 0) if (memcmp(digest, si.Hash, kHashSize) == 0)
prevSuccessStreamIndex = streamIndex; prevSuccessStreamIndex = streamIndex;
else else
opRes = NArchive::NExtract::NOperationResult::kCRCError; opRes = NExtract::NOperationResult::kCRCError;
} }
else if (res == S_FALSE) else if (res == S_FALSE)
opRes = NArchive::NExtract::NOperationResult::kDataError; opRes = NExtract::NOperationResult::kDataError;
else else
return res; return res;
} }

View File

@@ -107,6 +107,23 @@ struct CDatabase
{ {
CRecordVector<CStreamInfo> Streams; CRecordVector<CStreamInfo> Streams;
CObjectVector<CItem> Items; 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() void Clear()
{ {
Streams.Clear(); Streams.Clear();

View File

@@ -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;
}

View File

@@ -19,47 +19,13 @@
namespace NArchive { namespace NArchive {
namespace NZ { namespace NZ {
STATPROPSTG kProperties[] = STATPROPSTG kProps[] =
{ {
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidPackedSize, VT_UI8}, { NULL, kpidPackedSize, VT_UI8},
}; };
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value) IMP_IInArchive_Props
{ IMP_IInArchive_ArcProps_NO
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;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
@@ -67,24 +33,15 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK; 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 prop;
NWindows::NCOM::CPropVariant propVariant;
if (index != 0)
return E_INVALIDARG;
switch(propID) switch(propID)
{ {
case kpidIsFolder: case kpidPackedSize: prop = _packSize; break;
propVariant = false;
break;
case kpidPackedSize:
propVariant = _packSize;
break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END
} }
static const int kSignatureSize = 3; static const int kSignatureSize = 3;
@@ -151,9 +108,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(extractCallback->SetCompleted(&currentTotalPacked)); RINOK(extractCallback->SetCompleted(&currentTotalPacked));
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode = testMode ?
askMode = testMode ? NArchive::NExtract::NAskMode::kTest : NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract; NExtract::NAskMode::kExtract;
RINOK(extractCallback->GetStream(0, &realOutStream, askMode)); RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
@@ -164,13 +121,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CDummyOutStream *outStreamSpec = new CDummyOutStream; CDummyOutStream *outStreamSpec = new CDummyOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec); CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init(realOutStream); outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init();
realOutStream.Release(); realOutStream.Release();
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(extractCallback, true); lps->Init(extractCallback, false);
RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(_streamStartPosition + kSignatureSize, STREAM_SEEK_SET, NULL));
@@ -182,20 +139,20 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
int opResult; int opResult;
if (result != S_OK) if (result != S_OK)
opResult = NArchive::NExtract::NOperationResult::kUnSupportedMethod; opResult = NExtract::NOperationResult::kUnSupportedMethod;
else else
{ {
result = decoder->Code(_stream, outStream, NULL, NULL, progress); result = decoder->Code(_stream, outStream, NULL, NULL, progress);
outStream.Release();
if (result == S_FALSE) if (result == S_FALSE)
opResult = NArchive::NExtract::NOperationResult::kDataError; opResult = NExtract::NOperationResult::kDataError;
else if (result == S_OK)
opResult = NArchive::NExtract::NOperationResult::kOK;
else 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 COM_TRY_END
} }

View File

@@ -74,15 +74,7 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
static const wchar_t *kUnknownOS = L"Unknown"; static const wchar_t *kUnknownOS = L"Unknown";
STATPROPSTG kProps[] =
/*
enum // PropID
{
kpidUnPackVersion,
};
*/
STATPROPSTG kProperties[] =
{ {
{ NULL, kpidPath, VT_BSTR}, { NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidIsFolder, VT_BOOL},
@@ -99,7 +91,7 @@ STATPROPSTG kProperties[] =
{ NULL, kpidMethod, VT_BSTR}, { NULL, kpidMethod, VT_BSTR},
{ NULL, kpidHostOS, VT_BSTR} { NULL, kpidHostOS, VT_BSTR}
// { L"UnPack Version", kpidUnPackVersion, VT_UI1}, // { NULL, kpidUnpackVer, VT_UI1},
}; };
const wchar_t *kMethods[] = const wchar_t *kMethods[] =
@@ -147,7 +139,7 @@ CStrongCryptoPair g_StrongCryptoPairs[] =
{ NStrongCryptoFlags::kRC4, L"RC4" } { NStrongCryptoFlags::kRC4, L"RC4" }
}; };
STATPROPSTG kArcProperties[] = STATPROPSTG kArcProps[] =
{ {
{ NULL, kpidComment, VT_BSTR} { NULL, kpidComment, VT_BSTR}
}; };
@@ -158,7 +150,7 @@ CHandler::CHandler():
InitMethodProperties(); 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(); int size = (int)data.GetCapacity();
if (size <= 0) if (size <= 0)
@@ -168,62 +160,29 @@ static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM:
memcpy(p, (const Byte *)data, size); memcpy(p, (const Byte *)data, size);
p[size] = '\0'; p[size] = '\0';
s.ReleaseBuffer(); s.ReleaseBuffer();
propVariant = MultiByteToUnicodeString(s, codePage); prop = MultiByteToUnicodeString(s, codePage);
} }
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
switch(propID) switch(propID)
{ {
case kpidComment: case kpidComment:
{ {
StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, propVariant); StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, prop);
break; break;
} }
} }
propVariant.Detach(value); prop.Detach(value);
COM_TRY_END COM_TRY_END
return S_OK; 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) STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{ {
*numItems = m_Items.Size(); *numItems = m_Items.Size();
@@ -233,22 +192,22 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = m_Items[index]; const CItemEx &item = m_Items[index];
switch(propID) switch(propID)
{ {
case kpidPath: case kpidPath:
propVariant = NItemName::GetOSName2( prop = NItemName::GetOSName2(
MultiByteToUnicodeString(item.Name, item.GetCodePage())); MultiByteToUnicodeString(item.Name, item.GetCodePage()));
break; break;
case kpidIsFolder: case kpidIsFolder:
propVariant = item.IsDirectory(); prop = item.IsDirectory();
break; break;
case kpidSize: case kpidSize:
propVariant = item.UnPackSize; prop = item.UnPackSize;
break; break;
case kpidPackedSize: case kpidPackedSize:
propVariant = item.PackSize; prop = item.PackSize;
break; break;
case kpidLastWriteTime: case kpidLastWriteTime:
{ {
@@ -260,23 +219,23 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
} }
else else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
propVariant = utcFileTime; prop = utcFileTime;
break; break;
} }
case kpidAttributes: case kpidAttributes:
propVariant = item.GetWinAttributes(); prop = item.GetWinAttributes();
break; break;
case kpidEncrypted: case kpidEncrypted:
propVariant = item.IsEncrypted(); prop = item.IsEncrypted();
break; break;
case kpidComment: case kpidComment:
{ {
StringToProp(item.Comment, item.GetCodePage(), propVariant); StringToProp(item.Comment, item.GetCodePage(), prop);
break; break;
} }
case kpidCRC: case kpidCRC:
if (item.IsThereCrc()) if (item.IsThereCrc())
propVariant = item.FileCRC; prop = item.FileCRC;
break; break;
case kpidMethod: case kpidMethod:
{ {
@@ -335,15 +294,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
ConvertUInt64ToString(methodId, s); ConvertUInt64ToString(methodId, s);
method += s; method += s;
} }
propVariant = method; prop = method;
break; break;
} }
case kpidHostOS: case kpidHostOS:
propVariant = (item.MadeByVersion.HostOS < kNumHostOSes) ? prop = (item.MadeByVersion.HostOS < kNumHostOSes) ?
(kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS; (kHostOS[item.MadeByVersion.HostOS]) : kUnknownOS;
break; break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
@@ -731,15 +690,14 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
totalUnPacked += item.UnPackSize; totalUnPacked += item.UnPackSize;
totalPacked += item.PackSize; totalPacked += item.PackSize;
} }
extractCallback->SetTotal(totalUnPacked); RINOK(extractCallback->SetTotal(totalUnPacked));
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0; UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
UInt64 currentItemUnPacked, currentItemPacked; UInt64 currentItemUnPacked, currentItemPacked;
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; lps->Init(extractCallback, false);
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked) currentTotalPacked += currentItemPacked)
@@ -747,7 +705,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
currentItemUnPacked = 0; currentItemUnPacked = 0;
currentItemPacked = 0; currentItemPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalUnPacked)); lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ? Int32 askMode = testMode ?
NArchive::NExtract::NAskMode::kTest : NArchive::NExtract::NAskMode::kTest :
@@ -792,14 +753,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
localProgressSpec->Init(extractCallback, false);
localCompressProgressSpec->Init(progress, &currentTotalPacked, &currentTotalUnPacked);
Int32 res; Int32 res;
RINOK(myDecoder.Decode( RINOK(myDecoder.Decode(
EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS
m_Archive, item, realOutStream, extractCallback, m_Archive, item, realOutStream, extractCallback,
compressProgress, _numThreads, res)); progress, _numThreads, res));
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(res)) RINOK(extractCallback->SetOperationResult(res))

View File

@@ -542,6 +542,10 @@ HRESULT CInArchive::FindCd(CCdInfo &cdInfo)
// cdInfo.NumEntries = GetUInt16(buf + i + 10); // cdInfo.NumEntries = GetUInt16(buf + i + 10);
cdInfo.Size = GetUInt32(buf + i + 12); cdInfo.Size = GetUInt32(buf + i + 12);
cdInfo.Offset = GetUInt32(buf + i + 16); 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; return S_OK;
} }
} }

View File

@@ -226,7 +226,7 @@ public:
if (CentralExtra.GetWzAesField(aesField)) if (CentralExtra.GetWzAesField(aesField))
return aesField.NeedCrc(); return aesField.NeedCrc();
} }
return true; return (FileCRC != 0 || !IsDirectory());
} }
WORD GetCodePage() const WORD GetCodePage() const

View File

@@ -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 #endif
@@ -301,21 +382,20 @@ static HRESULT Update2St(
const CByteBuffer &comment, const CByteBuffer &comment,
IArchiveUpdateCallback *updateCallback) IArchiveUpdateCallback *updateCallback)
{ {
CLocalProgress *localProgressSpec = new CLocalProgress; CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = lps;
localProgressSpec->Init(updateCallback, true); lps->Init(updateCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
CAddCommon compressor(*options); CAddCommon compressor(*options);
CObjectVector<CItem> items; CObjectVector<CItem> items;
UInt64 complexity = 0; UInt64 unpackSizeTotal = 0, packSizeTotal = 0;
for (int itemIndex = 0; itemIndex < updateItems.Size(); itemIndex++) 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]; const CUpdateItem &updateItem = updateItems[itemIndex];
CItemEx item; CItemEx item;
if (!updateItem.NewProperties || !updateItem.NewData) if (!updateItem.NewProperties || !updateItem.NewData)
@@ -338,7 +418,7 @@ static HRESULT Update2St(
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
if (res == S_FALSE) if (res == S_FALSE)
{ {
complexity += updateItem.Size + NFileHeader::kLocalBlockSize; lps->ProgressOffset += updateItem.Size;
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
continue; continue;
} }
@@ -350,23 +430,26 @@ static HRESULT Update2St(
CCompressingResult compressingResult; CCompressingResult compressingResult;
CMyComPtr<IOutStream> outStream; CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream); archive.CreateStreamForCompressing(&outStream);
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
RINOK(compressor.Compress( RINOK(compressor.Compress(
EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS
fileInStream, outStream, compressProgress, compressingResult)); fileInStream, outStream, progress, compressingResult));
SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item); SetItemInfoFromCompressingResult(compressingResult, options->IsAesMode, options->AesKeyMode, item);
archive.WriteLocalHeader(item); archive.WriteLocalHeader(item);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
complexity += item.UnPackSize; unpackSizeTotal += item.UnPackSize;
packSizeTotal += item.PackSize;
} }
} }
else else
{ {
localCompressProgressSpec->Init(localProgress, &complexity, NULL); UInt64 complexity = 0;
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, compressProgress, complexity)); lps->SendRatio = false;
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
lps->SendRatio = true;
lps->ProgressOffset += complexity;
} }
items.Add(item); items.Add(item);
complexity += NFileHeader::kLocalBlockSize; lps->ProgressOffset += NFileHeader::kLocalBlockSize;
} }
archive.WriteCentralDir(items, comment); archive.WriteCentralDir(items, comment);
return S_OK; return S_OK;
@@ -477,17 +560,12 @@ static HRESULT Update2(
CObjectVector<CItem> items; CObjectVector<CItem> items;
CLocalProgress *localProgressSpec = new CLocalProgress; CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; CMyComPtr<ICompressProgressInfo> progress = mtProgressMixerSpec;
localProgressSpec->Init(updateCallback, true); mtProgressMixerSpec->Create(updateCallback, true);
CMtCompressProgressMixer mtCompressProgressMixer; CMtCompressProgressMixer mtCompressProgressMixer;
mtCompressProgressMixer.Init(numThreads + 1, localProgress); mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress);
// we need one item for main stream
CMtCompressProgress *progressMainSpec = new CMtCompressProgress();
CMyComPtr<ICompressProgressInfo> progressMain = progressMainSpec;
progressMainSpec->Init(&mtCompressProgressMixer, (int)numThreads);
CMemBlockManagerMt memManager(kBlockSize); CMemBlockManagerMt memManager(kBlockSize);
CMemRefs refs(&memManager); CMemRefs refs(&memManager);
@@ -551,12 +629,13 @@ static HRESULT Update2(
} }
CMyComPtr<ISequentialInStream> fileInStream; CMyComPtr<ISequentialInStream> fileInStream;
{ {
NWindows::NSynchronization::CCriticalSectionLock lock(mtCompressProgressMixer.CriticalSection); NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection);
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream); HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
if (res == S_FALSE) if (res == S_FALSE)
{ {
complexity += updateItem.Size; complexity += updateItem.Size;
complexity++; complexity += NFileHeader::kLocalBlockSize;
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
refs.Refs[mtItemIndex - 1].Skip = true; refs.Refs[mtItemIndex - 1].Skip = true;
continue; continue;
@@ -633,7 +712,6 @@ static HRESULT Update2(
options->IsAesMode, options->AesKeyMode, item); options->IsAesMode, options->AesKeyMode, item);
SetFileHeader(archive, *options, updateItem, item); SetFileHeader(archive, *options, updateItem, item);
archive.WriteLocalHeader(item); archive.WriteLocalHeader(item);
complexity += item.UnPackSize;
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); // RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
memRef.FreeOpt(&memManager); memRef.FreeOpt(&memManager);
} }
@@ -667,7 +745,6 @@ static HRESULT Update2(
options->IsAesMode, options->AesKeyMode, item); options->IsAesMode, options->AesKeyMode, item);
SetFileHeader(archive, *options, updateItem, item); SetFileHeader(archive, *options, updateItem, item);
archive.WriteLocalHeader(item); archive.WriteLocalHeader(item);
complexity += item.UnPackSize;
} }
else else
{ {
@@ -682,11 +759,11 @@ static HRESULT Update2(
} }
else else
{ {
progressMainSpec->Reinit(); RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progressMain, complexity));
} }
items.Add(item); items.Add(item);
complexity += NFileHeader::kLocalBlockSize; complexity += NFileHeader::kLocalBlockSize;
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
itemIndex++; itemIndex++;
} }
archive.WriteCentralDir(items, comment); archive.WriteCentralDir(items, comment);

View File

@@ -2411,12 +2411,20 @@ SOURCE=..\..\ICoder.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\IDecl.h
# End Source File
# Begin Source File
SOURCE=..\..\IPassword.h SOURCE=..\..\IPassword.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\IProgress.h SOURCE=..\..\IProgress.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\..\IStream.h
# End Source File
# End Group # End Group
# Begin Source File # Begin Source File

View File

@@ -389,11 +389,12 @@ int Main2(
eo.YesToAll = yesToAll; eo.YesToAll = yesToAll;
UString errorMessage; UString errorMessage;
CDecompressStat stat;
HRESULT result = DecompressArchives( HRESULT result = DecompressArchives(
codecs, codecs,
v1, v2, v1, v2,
wildcardCensorHead, wildcardCensorHead,
eo, &openCallback, ecs, errorMessage); eo, &openCallback, ecs, errorMessage, stat);
if (!errorMessage.IsEmpty()) if (!errorMessage.IsEmpty())
{ {
(*g_StdStream) << endl << "Error: " << errorMessage;; (*g_StdStream) << endl << "Error: " << errorMessage;;

View File

@@ -240,7 +240,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResul
} }
} }
if(_outFileStream != NULL) if(_outFileStream != NULL)
_outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime); _outFileStreamSpec->SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
_outFileStream.Release(); _outFileStream.Release();
if (_extractMode) if (_extractMode)
NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes); NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);

View File

@@ -13,7 +13,7 @@
#include "../../ICoder.h" #include "../../ICoder.h"
#ifndef _NO_PROGRESS #ifndef _NO_PROGRESS
#include "../../FileManager/Resource/ProgressDialog/ProgressDialog.h" #include "../../UI/FileManager/ProgressDialog.h"
#endif #endif
class CExtractCallbackImp: class CExtractCallbackImp:

View File

@@ -13,7 +13,7 @@
#include "../../UI/Common/OpenArchive.h" #include "../../UI/Common/OpenArchive.h"
#include "../../UI/Explorer/MyMessages.h" #include "../../UI/Explorer/MyMessages.h"
#include "../../FileManager/FormatUtils.h" #include "../../UI/FileManager/FormatUtils.h"
#include "ExtractCallback.h" #include "ExtractCallback.h"

View File

@@ -668,20 +668,20 @@ SOURCE=..\..\UI\GUI\OpenCallbackGUI.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp SOURCE=..\..\UI\FileManager\ProgressDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h SOURCE=..\..\UI\FileManager\ProgressDialog.h
# End Source File # End Source File
# End Group # End Group
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\FormatUtils.cpp SOURCE=..\..\UI\FileManager\FormatUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\FormatUtils.h SOURCE=..\..\UI\FileManager\FormatUtils.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "C" # Begin Group "C"

View File

@@ -64,6 +64,7 @@ UI_COMMON_OBJS = \
FM_OBJS = \ FM_OBJS = \
$O\FormatUtils.obj \ $O\FormatUtils.obj \
$O\ProgressDialog.obj \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
@@ -125,7 +126,6 @@ OBJS = \
$(LZ_OBJS) \ $(LZ_OBJS) \
$(LZMA_OPT_OBJS) \ $(LZMA_OPT_OBJS) \
$O\MyMessages.obj \ $O\MyMessages.obj \
$O\ProgressDialog.obj \
$(C_OBJS) \ $(C_OBJS) \
$(C_BRANCH_OBJS) \ $(C_BRANCH_OBJS) \
$(CRC_OBJS) \ $(CRC_OBJS) \
@@ -149,7 +149,7 @@ $(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL) $(COMPL)
$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp $(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
$(COMPL) $(COMPL)
$(FM_OBJS): ../../FileManager/$(*B).cpp $(FM_OBJS): ../../UI/FileManager//$(*B).cpp
$(COMPL) $(COMPL)
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp $(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
$(COMPL) $(COMPL)
@@ -167,8 +167,6 @@ $(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp $O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
$(COMPL) $(COMPL)
$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog/$(*B).cpp
$(COMPL)
$(C_OBJS): ../../../../C/$(*B).c $(C_OBJS): ../../../../C/$(*B).c
$(COMPL_O1) $(COMPL_O1)

View File

@@ -13,4 +13,4 @@ BEGIN
IDS_PROGRESS_EXTRACTING "Extracting" IDS_PROGRESS_EXTRACTING "Extracting"
END END
#include "../../FileManager/Resource/ProgressDialog/resource.rc" #include "../../UI/FileManager/ProgressDialog.rc"

View File

@@ -389,35 +389,35 @@ SOURCE=..\..\Crypto\Hash\Sha256.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h SOURCE=..\..\UI\FileManager\MessagesDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h SOURCE=..\..\UI\FileManager\OverwriteDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp SOURCE=..\..\UI\FileManager\PasswordDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h SOURCE=..\..\UI\FileManager\PasswordDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.cpp SOURCE=..\..\UI\FileManager\ProgressDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\Resource\ProgressDialog\ProgressDialog.h SOURCE=..\..\UI\FileManager\ProgressDialog.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "7zip Common" # Begin Group "7zip Common"
@@ -533,19 +533,19 @@ SOURCE=..\..\Common\VirtThread.h
# PROP Default_Filter "" # PROP Default_Filter ""
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\ExtractCallback.cpp SOURCE=..\..\UI\FileManager\ExtractCallback.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\ExtractCallback.h SOURCE=..\..\UI\FileManager\ExtractCallback.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\FormatUtils.cpp SOURCE=..\..\UI\FileManager\FormatUtils.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\FileManager\FormatUtils.h SOURCE=..\..\UI\FileManager\FormatUtils.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Windows" # Begin Group "Windows"

View File

@@ -68,6 +68,10 @@ UI_COMMON_OBJS = \
FM_OBJS = \ FM_OBJS = \
$O\ExtractCallback.obj \ $O\ExtractCallback.obj \
$O\FormatUtils.obj \ $O\FormatUtils.obj \
$O\MessagesDialog.obj \
$O\OverwriteDialog.obj \
$O\PasswordDialog.obj \
$O\ProgressDialog.obj \
AR_COMMON_OBJS = \ AR_COMMON_OBJS = \
$O\CoderMixer2.obj \ $O\CoderMixer2.obj \
@@ -150,10 +154,6 @@ OBJS = \
$(7ZAES_OPT_OBJS) \ $(7ZAES_OPT_OBJS) \
$(AES_OPT_OBJS) \ $(AES_OPT_OBJS) \
$O\MyMessages.obj \ $O\MyMessages.obj \
$O\MessagesDialog.obj \
$O\OverwriteDialog.obj \
$O\PasswordDialog.obj \
$O\ProgressDialog.obj \
$(C_OBJS) \ $(C_OBJS) \
$(C_BRANCH_OBJS) \ $(C_BRANCH_OBJS) \
$(CRC_OBJS) \ $(CRC_OBJS) \
@@ -178,7 +178,7 @@ $(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
$(COMPL) $(COMPL)
$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp $(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
$(COMPL) $(COMPL)
$(FM_OBJS): ../../FileManager/$(*B).cpp $(FM_OBJS): ../../UI/FileManager/$(*B).cpp
$(COMPL) $(COMPL)
$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp $(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
$(COMPL) $(COMPL)
@@ -205,14 +205,6 @@ $(AES_OPT_OBJS): ../../Crypto/AES/$(*B).cpp
$O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp $O\MyMessages.obj: ../../UI/Explorer/MyMessages.cpp
$(COMPL) $(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 $(C_OBJS): ../../../../C/$(*B).c
$(COMPL_O1) $(COMPL_O1)
$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c $(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c

View File

@@ -27,8 +27,8 @@ BEGIN
PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
END END
#include "../../FileManager/Resource/MessagesDialog/resource.rc" #include "../../UI/FileManager/MessagesDialog.rc"
#include "../../FileManager/Resource/OverwriteDialog/resource.rc" #include "../../UI/FileManager/OverwriteDialog.rc"
#include "../../FileManager/Resource/PasswordDialog/resource.rc" #include "../../UI/FileManager/PasswordDialog.rc"
#include "../../FileManager/Resource/ProgressDialog/resource.rc" #include "../../UI/FileManager/ProgressDialog.rc"
#include "../../UI/Resource/Extract/resource.rc" #include "../../UI/GUI/Extract.rc"

View File

@@ -12,9 +12,13 @@
static inline HRESULT ConvertBoolToHRESULT(bool result) static inline HRESULT ConvertBoolToHRESULT(bool result)
{ {
// return result ? S_OK: E_FAIL;
#ifdef _WIN32 #ifdef _WIN32
return result ? S_OK: (::GetLastError()); if (result)
return S_OK;
DWORD lastError = ::GetLastError();
if (lastError == 0)
return E_FAIL;
return lastError;
#else #else
return result ? S_OK: E_FAIL; return result ? S_OK: E_FAIL;
#endif #endif
@@ -141,26 +145,13 @@ STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
////////////////////////// //////////////////////////
// COutFileStream // 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) STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{ {
#ifdef USE_WIN_FILE #ifdef USE_WIN_FILE
UInt32 realProcessedSize; UInt32 realProcessedSize;
bool result = File.WritePart(data, size, realProcessedSize); bool result = File.WritePart(data, size, realProcessedSize);
ProcessedSize += realProcessedSize;
if(processedSize != NULL) if(processedSize != NULL)
*processedSize = realProcessedSize; *processedSize = realProcessedSize;
return ConvertBoolToHRESULT(result); return ConvertBoolToHRESULT(result);
@@ -174,13 +165,13 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces
return E_FAIL; return E_FAIL;
if(processedSize != NULL) if(processedSize != NULL)
*processedSize = (UInt32)res; *processedSize = (UInt32)res;
ProcessedSize += res;
return S_OK; return S_OK;
#endif #endif
} }
STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
UInt64 *newPosition)
{ {
if(seekOrigin >= 3) if(seekOrigin >= 3)
return STG_E_INVALIDFUNCTION; return STG_E_INVALIDFUNCTION;

View File

@@ -72,20 +72,52 @@ class COutFileStream:
public IOutStream, public IOutStream,
public CMyUnknownImp public CMyUnknownImp
{ {
public:
#ifdef USE_WIN_FILE #ifdef USE_WIN_FILE
NWindows::NFile::NIO::COutFile File; NWindows::NFile::NIO::COutFile File;
#else #else
NC::NFile::NIO::COutFile File; NC::NFile::NIO::COutFile File;
#endif #endif
public:
virtual ~COutFileStream() {} 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 #ifdef USE_WIN_FILE
#ifndef _UNICODE #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
#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) MY_UNKNOWN_IMP1(IOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);

View File

@@ -109,7 +109,7 @@ HRESULT COutBuffer::Flush()
void COutBuffer::FlushWithCheck() void COutBuffer::FlushWithCheck()
{ {
HRESULT result = FlushPart(); HRESULT result = Flush();
#ifdef _NO_EXCEPTIONS #ifdef _NO_EXCEPTIONS
ErrorCode = result; ErrorCode = result;
#else #else

View File

@@ -4,52 +4,37 @@
#include "ProgressUtils.h" #include "ProgressUtils.h"
void CLocalCompressProgressInfo::Init(ICompressProgressInfo *progress, CLocalProgress::CLocalProgress()
const UInt64 *inStartValue, const UInt64 *outStartValue)
{ {
_progress = progress; ProgressOffset = InSize = OutSize = 0;
_inStartValueIsAssigned = (inStartValue != NULL); SendRatio = true;
if (_inStartValueIsAssigned)
_inStartValue = *inStartValue;
_outStartValueIsAssigned = (outStartValue != NULL);
if (_outStartValueIsAssigned)
_outStartValue = *outStartValue;
} }
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) void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
{ {
_ratioProgress.Release();
_progress = progress; _progress = progress;
_progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress);
_inSizeIsMain = inSizeIsMain; _inSizeIsMain = inSizeIsMain;
} }
STDMETHODIMP CLocalProgress::SetRatioInfo( STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
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);
} }

View File

@@ -8,32 +8,22 @@
#include "../ICoder.h" #include "../ICoder.h"
#include "../IProgress.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: class CLocalProgress:
public ICompressProgressInfo, public ICompressProgressInfo,
public CMyUnknownImp public CMyUnknownImp
{ {
CMyComPtr<IProgress> _progress; CMyComPtr<IProgress> _progress;
CMyComPtr<ICompressProgressInfo> _ratioProgress;
bool _inSizeIsMain; bool _inSizeIsMain;
public: public:
UInt64 ProgressOffset;
UInt64 InSize;
UInt64 OutSize;
bool SendRatio;
CLocalProgress();
void Init(IProgress *progress, bool inSizeIsMain); void Init(IProgress *progress, bool inSizeIsMain);
HRESULT SetCur();
MY_UNKNOWN_IMP MY_UNKNOWN_IMP

View File

@@ -38,7 +38,7 @@ HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size,
size -= processedSizeLoc; size -= processedSizeLoc;
RINOK(res); RINOK(res);
if (processedSizeLoc == 0) if (processedSizeLoc == 0)
break; return E_FAIL;
} }
return S_OK; return S_OK;
} }

View File

@@ -238,6 +238,13 @@ HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
if (progress != NULL) if (progress != NULL)
{ {
/*
const UInt64 compressedSize =
_mainStream.GetProcessedSize() +
_callStream.GetProcessedSize() +
_jumpStream.GetProcessedSize() +
_rangeEncoder.GetProcessedSize();
*/
RINOK(progress->SetRatioInfo(&nowPos64, NULL)); RINOK(progress->SetRatioInfo(&nowPos64, NULL));
} }
@@ -312,7 +319,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
{ {
if (processedBytes >= (1 << 20) && progress != NULL) 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)); RINOK(progress->SetRatioInfo(NULL, &nowPos64));
processedBytes = 0; processedBytes = 0;
} }

View File

@@ -463,14 +463,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
ICompressProgressInfo *progress) ICompressProgressInfo *progress)
{ {
try try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
{ catch(const CInBufferException &e) { return e.ErrorCode; }
HRESULT res = CodeReal(inStream, outStream, inSize, outSize, progress); catch(const CLZOutWindowException &e) { return e.ErrorCode; }
m_OutWindowStream.Flush(); catch(...) { return S_FALSE; }
return res;
}
catch(const CLZOutWindowException &e) { m_OutWindowStream.Flush(); return e.ErrorCode; }
catch(...) { m_OutWindowStream.Flush(); return S_FALSE; }
} }
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)

View File

@@ -385,6 +385,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
ICompressProgressInfo *progress) ICompressProgressInfo *progress)
{ {
try { return CodeReal(inStream, outStream, inSize, outSize, progress); } try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
catch(const CInBufferException &e) { return e.ErrorCode; }
catch(const CLZOutWindowException &e) { return e.ErrorCode; } catch(const CLZOutWindowException &e) { return e.ErrorCode; }
catch(...) { return S_FALSE; } catch(...) { return S_FALSE; }
} }

View File

@@ -52,8 +52,8 @@ CDecoder::CDecoder():
CDecoder::~CDecoder() CDecoder::~CDecoder()
{ {
InitFilters(); InitFilters();
if (_vmData)
::MidFree(_vmData); ::MidFree(_vmData);
::MidFree(_window);
} }
HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size) HRESULT CDecoder::WriteDataToStream(const Byte *data, UInt32 size)
@@ -821,6 +821,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
_unpackSize = *outSize; _unpackSize = *outSize;
return CodeReal(progress); return CodeReal(progress);
} }
catch(const CInBufferException &e) { return e.ErrorCode; }
catch(...) { return S_FALSE; } catch(...) { return S_FALSE; }
// CNewException is possible here. But probably CNewException is caused // CNewException is possible here. But probably CNewException is caused
// by error in data stream. // by error in data stream.

View File

@@ -35,13 +35,12 @@ const UInt32 kLevelTableSize = 20;
const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize;
template<class TInByte> class CBitDecoder
class CBitDecoder2
{ {
UInt32 m_Value; UInt32 m_Value;
public: public:
UInt32 m_BitPos; UInt32 m_BitPos;
TInByte m_Stream; CInBuffer m_Stream;
bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}
void ReleaseStream() { m_Stream.ReleaseStream();} void ReleaseStream() { m_Stream.ReleaseStream();}
@@ -98,8 +97,6 @@ public:
} }
}; };
typedef CBitDecoder2<CInBuffer> CBitDecoder;
const int kNumTopBits = 24; const int kNumTopBits = 24;
const UInt32 kTopValue = (1 << kNumTopBits); const UInt32 kTopValue = (1 << kNumTopBits);
const UInt32 kBot = (1 << 15); const UInt32 kBot = (1 << 15);

View File

@@ -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

View File

@@ -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

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,3 +0,0 @@
#define IDD_DIALOG_LISTBOX 202
#define IDC_LISTBOX_LIST 1000

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,11 +1,19 @@
{23170F69-40C1-278A-0000-} {23170F69-40C1-278A-0000-00yy00xx0000}
000000xx0000 IProgress.h 00 IProgress.h
05 IProgress 05 IProgress
01 IFolderArchive.h
000300xx0000 IStream.h 05 IArchiveFolder
06 IInFolderArchive
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
0A IOutFolderArchive
0B IFolderArchiveUpdateCallback
0<> Agent.h::IArchiveFolderInternal
03 IStream.h
01 ISequentialInStream 01 ISequentialInStream
02 ISequentialOutStream 02 ISequentialOutStream
@@ -15,7 +23,7 @@
07 IOutStreamFlush 07 IOutStreamFlush
000400xx0000 ICoder.h 04 ICoder.h
04 ICompressProgressInfo 04 ICompressProgressInfo
05 ICompressCoder 05 ICompressCoder
@@ -41,13 +49,13 @@
A0 ICryptoSetCRC A0 ICryptoSetCRC
000500xx0000 IPassword.h 05 IPassword.h
10 ICryptoGetTextPassword 10 ICryptoGetTextPassword
11 ICryptoGetTextPassword2 11 ICryptoGetTextPassword2
000600xx0000 IArchive.h 06 IArchive.h
03 ISetProperties 03 ISetProperties
@@ -63,42 +71,31 @@ A0 ICryptoSetCRC
A0 IOutArchive A0 IOutArchive
000100050001 Agent.h::IArchiveFolderInternal
08 IFolder.h
000100xx0000 IFolderArchive.h
05 IArchiveFolder
06 IInFolderArchive
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
0A IOutFolderArchive
0B IFolderArchiveUpdateCallback
000800xxyy00 FolderInterface.h::
00 IFolderFolder 00 IFolderFolder
01 IEnumProperties 01 IEnumProperties
02 IFolderGetTypeID 02 IFolderGetTypeID
03 IFolderGetPath 03 IFolderGetPath
04 IFolderWasChanged 04 IFolderWasChanged
05 IFolderReload // 05 // IFolderReload
0504 IFolderChangeNotify
0505 IFolderSetChangeNotify
050A IFolderExtract //
06 IFolderOperations 06 IFolderOperations
0601 IFolderOperationsExtractCallback
0602 IFolderOperationsUpdateCallback //
0603 IFolderOperationsDeleteToRecycleBin //
07 IFolderGetSystemIconIndex 07 IFolderGetSystemIconIndex
08 IFolderGetItemFullSize 08 IFolderGetItemFullSize
09 IFolderClone 09 IFolderClone
0A IFolderSetFlatMode 0A IFolderSetFlatMode
0B IFolderOperationsExtractCallback
000900000000} FolderInterface.h::IFolderManager
000900010000} FolderInterface.h::IFolderManagerGetIconPath 09 FolderInterface.h
00 // old IFolderManager
01 IFolderManager
------------------
{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu {23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu
@@ -142,4 +139,3 @@ EF GZip
{23170F69-40C1-2790-id} Codec Decoders {23170F69-40C1-2790-id} Codec Decoders
{23170F69-40C1-2791-id} Codec Encoders {23170F69-40C1-2791-id} Codec Encoders

View File

@@ -5,11 +5,7 @@
#include "IStream.h" #include "IStream.h"
// "23170F69-40C1-278A-0000-000400xx0000" #define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)
#define CODER_INTERFACE(i, x) \
DEFINE_GUID(IID_ ## i, \
0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
struct i: public IUnknown
CODER_INTERFACE(ICompressProgressInfo, 0x04) CODER_INTERFACE(ICompressProgressInfo, 0x04)
{ {

15
CPP/7zip/IDecl.h Executable file
View File

@@ -0,0 +1,15 @@
// IDecl.h
#ifndef __IDECL_H
#define __IDECL_H
#include "../Common/MyUnknown.h"
#define DECL_INTERFACE_SUB(i, base, groupId, subId) \
DEFINE_GUID(IID_ ## i, \
0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \
struct i: public base
#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId)
#endif

Some files were not shown because too many files have changed in this diff Show More