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
+17 -3
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));
+16 -12
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
+84 -51
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);
} }
+7
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;
}
}; };
}} }}
+2 -6
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]);
+26 -70
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;
+7 -7
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;
} }
+96 -269
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,149 +244,63 @@ 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
{
result = copyCoder->Code(inStream, outStream,
NULL, NULL, compressProgress);
}
if (result == S_FALSE)
throw "data error";
if (result != S_OK)
return result;
}
catch(...)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kDataError));
continue;
}
break;
}
case NFileHeader::NCompressionMethod::kCompressed1a:
case NFileHeader::NCompressionMethod::kCompressed1b:
case NFileHeader::NCompressionMethod::kCompressed1c:
{
if(!arj1Decoder)
{
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
}
try
{
if (itemInfo.IsEncrypted())
{
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
else
{
result = arj1Decoder->Code(inStream, outStream,
NULL, &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;
}
case NFileHeader::NCompressionMethod::kCompressed2:
{
if(!arj2Decoder)
{
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
}
try
{
if (itemInfo.IsEncrypted())
{
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
else
{
result = arj2Decoder->Code(inStream, outStream,
NULL, &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;
}
default:
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kUnSupportedMethod));
continue;
}
bool crcOK = outStreamSpec->GetCRC() == itemInfo.FileCRC;
outStream.Release();
if(crcOK)
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
else else
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)) {
switch(item.Method)
{
case NFileHeader::NCompressionMethod::kStored:
{
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
result = S_FALSE;
break;
}
case NFileHeader::NCompressionMethod::kCompressed1a:
case NFileHeader::NCompressionMethod::kCompressed1b:
case NFileHeader::NCompressionMethod::kCompressed1c:
{
if (!arj1Decoder)
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
result = arj1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
break;
}
case NFileHeader::NCompressionMethod::kCompressed2:
{
if (!arj2Decoder)
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
result = arj2Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
break;
}
default:
opRes = NExtract::NOperationResult::kUnSupportedMethod;
}
}
if (opRes == NExtract::NOperationResult::kOK)
{
if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else
{
RINOK(result);
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kCRCError;
}
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
} }
} }
return S_OK; return S_OK;
-1
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;
+28 -82
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
} }
+10 -11
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;
+87 -60
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;
for (int v = 0; v < m_Database.Volumes.Size(); v++)
{
const CDatabaseEx &de = m_Database.Volumes[v];
for (i = 0; i < de.Folders.Size(); i++)
ids.AddToUniqueSorted(de.Folders[i].GetCompressionMethod());
}
for (i = 0; i < ids.Size(); i++)
{
Byte id = ids[i];
UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
if (!resString.IsEmpty())
resString += L' ';
resString += method;
}
prop = resString;
break;
}
// case kpidSolid: prop = _database.IsSolid(); break;
case kpidNumBlocks:
{
UInt32 numFolders = 0;
for (int v = 0; v < m_Database.Volumes.Size(); v++)
numFolders += m_Database.Volumes[v].Folders.Size();
prop = numFolders;
break;
}
case kpidNumVolumes:
{
prop = (UInt32)m_Database.Volumes.Size();
break;
}
}
prop.Detach(value);
return S_OK; return S_OK;
} COM_TRY_END
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::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);
+84 -88
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
} }
@@ -295,7 +295,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
{ {
if (m_FileIsOpen) if (m_FileIsOpen)
return S_OK; return S_OK;
for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) for (;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
{ {
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
if (fileSize != 0) if (fileSize != 0)
@@ -421,17 +421,23 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
(m_Database.LowLevel ? (m_Database.LowLevel ?
m_Database.Items.Size(): m_Database.Items.Size():
m_Database.Indices.Size()); m_Database.Indices.Size());
if(numItems == 0) if (numItems == 0)
return S_OK; return S_OK;
bool testMode = (_aTestMode != 0); bool testMode = (_aTestMode != 0);
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)
{ {
@@ -440,17 +446,21 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
if (m_Database.NewFormat) if (m_Database.NewFormat)
totalSize = m_Database.NewFormatString.Length(); totalSize = m_Database.NewFormatString.Length();
else else
for(i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size;
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
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));
@@ -458,7 +468,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
{ {
if (index != 0) if (index != 0)
return E_FAIL; return E_FAIL;
if(!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
continue; continue;
if (!testMode) if (!testMode)
{ {
@@ -472,7 +482,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
currentItemSize = item.Size; currentItemSize = item.Size;
if(!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
if (item.Section != 0) if (item.Section != 0)
@@ -488,28 +498,19 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
} }
RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); 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;
} }
UInt64 lastFolderIndex = ((UInt64)0 - 1); UInt64 lastFolderIndex = ((UInt64)0 - 1);
for(i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{ {
UInt32 index = allFilesMode ? i : indices[i]; UInt32 index = allFilesMode ? i : indices[i];
int entryIndex = m_Database.Indices[index]; int entryIndex = m_Database.Indices[index];
@@ -545,7 +546,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
currentTotalSize = 0; currentTotalSize = 0;
CRecordVector<bool> extractStatuses; CRecordVector<bool> extractStatuses;
for(i = 0; i < numItems;) for (i = 0; i < numItems;)
{ {
RINOK(extractCallback->SetCompleted(&currentTotalSize)); RINOK(extractCallback->SetCompleted(&currentTotalSize));
UInt32 index = allFilesMode ? i : indices[i]; UInt32 index = allFilesMode ? i : indices[i];
@@ -566,32 +567,27 @@ 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)
{ {
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
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;
} }
@@ -652,7 +648,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
chmFolderOutStream->m_StartIndex = index; chmFolderOutStream->m_StartIndex = index;
if (limitFolderIndex == folderIndex) if (limitFolderIndex == folderIndex)
{ {
for(; i < numItems; i++) for (; i < numItems; i++)
{ {
UInt32 nextIndex = allFilesMode ? i : indices[i]; UInt32 nextIndex = allFilesMode ? i : indices[i];
int entryIndex = m_Database.Indices[nextIndex]; int entryIndex = m_Database.Indices[nextIndex];
+24 -41
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
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidClusterSize: prop = (UInt32)1 << _db.SectorSizeBits; 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;
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
} }
+1 -1
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;
+1 -1
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)
+12 -12
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;
+1
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
+12 -12
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;
+1
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
+13 -11
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)
STDMETHODIMP CDummyOutStream::Write(const void *data, {
UInt32 size, UInt32 *processedSize) realProcessedSize = size;
{ result = S_OK;
if(m_Stream) }
return m_Stream->Write(data, size, processedSize); else
result = _stream->Write(data, size, &realProcessedSize);
_size += realProcessedSize;
if(processedSize != NULL) if(processedSize != NULL)
*processedSize = size; *processedSize = realProcessedSize;
return S_OK; return result;
} }
+5 -5
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
+67 -121
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;
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&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;
RINOK(extractCallback->PrepareOperation(askMode));
if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
{ streamSpec->Init(item.Size);
if (testMode) RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
{ realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
continue; NArchive::NExtract::NOperationResult::kOK:
} NArchive::NExtract::NOperationResult::kDataError));
RINOK(m_InStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(m_InStream);
streamSpec->Init(itemInfo.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalSize, &currentTotalSize);
if(copyCoder == NULL)
{
copyCoder = new NCompress::CCopyCoder;
}
try
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
+2 -2
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;
}; };
}} }}
+49 -102
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,83 +135,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 = _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 += _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;
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&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;
RINOK(extractCallback->PrepareOperation(askMode));
if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
{ streamSpec->Init(item.Size);
if (testMode) RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
{ realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
continue; NArchive::NExtract::NOperationResult::kOK:
} NArchive::NExtract::NOperationResult::kDataError));
RINOK(_inStream->Seek(itemInfo.GetDataPosition(), STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
streamSpec->Init(itemInfo.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalSize, &currentTotalSize);
if(copyCoder == NULL)
{
copyCoder = new NCompress::CCopyCoder;
}
try
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
+50 -103
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,45 +247,32 @@ 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)
{
RINOK(CreateCoder(
EXTERNAL_CODECS_VARS
kMethodId_Deflate, deflateDecoder, false));
if (!deflateDecoder)
{ {
if(!deflateDecoder) opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
{
RINOK(CreateCoder(
EXTERNAL_CODECS_VARS
kMethodId_Deflate, deflateDecoder, false));
if (!deflateDecoder)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
return S_OK;
}
}
try
{
HRESULT result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, compressProgress);
if (result == S_FALSE)
throw "data error";
if (result != S_OK)
return result;
}
catch(...)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(
NArchive::NExtract::NOperationResult::kDataError));
return S_OK;
}
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
+23 -23
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;
+5 -13
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();
+38 -6
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
+37 -85
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;
@@ -252,47 +230,21 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
blockIndex = be.LoadRBA; blockIndex = be.LoadRBA;
} }
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));
{ continue;
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue;
}
RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
streamSpec->Init(currentItemSize);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, &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();
RINOK(extractCallback->SetOperationResult(res));
} }
RINOK(_inStream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
realOutStream.Release();
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == currentItemSize) ?
NArchive::NExtract::NOperationResult::kOK:
NArchive::NExtract::NOperationResult::kDataError));
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
+72 -145
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(...)
{
outStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
} }
else if (itemInfo.IsLh4GroupMethod()) else if (item.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)
{
if (result == S_FALSE)
opRes = NExtract::NOperationResult::kDataError;
else
{
RINOK(result);
if (outStreamSpec->GetCRC() != item.CRC)
opRes = NExtract::NOperationResult::kCRCError;
}
}
outStream.Release(); outStream.Release();
if(crcOK) RINOK(extractCallback->SetOperationResult(opRes));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK))
else
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError))
} }
} }
return S_OK; return S_OK;
+66 -61
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,8 +484,7 @@ 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 :
NArchive::NExtract::NOperationResult::kOK)); NArchive::NExtract::NOperationResult::kOK));
+1
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
+2 -2
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++;
+13 -69
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();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
return S_OK;
}
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
} }
+87 -189
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;
}
case kpidNumVolumes: prop = (UInt32)(_archives.Size() - 1);
// case kpidCommented: prop = _archiveInfo.IsCommented(); break;
} }
propVariant.Detach(value); prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
return E_INVALIDARG;
const STATPROPSTG &srcItem = kProperties[index];
*propID = srcItem.propid;
*varType = srcItem.vt;
*name = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{
*numProperties = 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)
+1 -1
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
+2 -2
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; }
+1 -1
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)
+30 -85
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;
for(int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize) CLocalProgress *lps = new CLocalProgress;
{ CMyComPtr<ICompressProgressInfo> progress = lps;
// CMyComPtr<ISequentialInStream> inStream; lps->Init(extractCallback, false);
// RINOK(volumeExtractCallback->GetInStream(_names[i], &inStream));
CLocalProgress *localProgressSpec = new CLocalProgress; for (int i = 0; i < _streams.Size(); i++, currentTotalSize += currentItemSize)
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; {
localProgressSpec->Init(extractCallback, false); lps->InSize = lps->OutSize = currentTotalSize;
CLocalCompressProgressInfo *localCompressProgressSpec = RINOK(lps->SetCur());
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
} }
+14 -14
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;
+55 -104
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 */,
@@ -81,7 +57,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{ {
CInArchive archive; CInArchive archive;
if(archive.Open(stream) != S_OK) if (archive.Open(stream) != S_OK)
return S_FALSE; return S_FALSE;
_items.Clear(); _items.Clear();
@@ -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,86 +184,61 @@ 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;
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;
for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{ {
RINOK(extractCallback->SetCompleted(&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));
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
if(!testMode && (!realOutStream)) if (!testMode && (!realOutStream))
continue;
RINOK(extractCallback->PrepareOperation(askMode));
if (testMode)
{ {
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
continue; continue;
} }
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
{ streamSpec->Init(item.Size);
if (testMode) RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
{ realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
continue; NArchive::NExtract::NOperationResult::kOK:
} NArchive::NExtract::NOperationResult::kDataError));
RINOK(_inStream->Seek(item.GetDataPosition(), STREAM_SEEK_SET, NULL));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(streamSpec);
streamSpec->SetStream(_inStream);
streamSpec->Init(item.Size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress,
&currentTotalSize, &currentTotalSize);
if(!copyCoder)
{
copyCoder = new NCompress::CCopyCoder;
}
try
{
RINOK(copyCoder->Code(inStream, realOutStream,
NULL, NULL, compressProgress));
}
catch(...)
{
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError));
continue;
}
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
}
} }
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
+23 -23
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;
} }
+31 -48
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;
@@ -76,13 +64,13 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
item.Name = (updateItem.Name); item.Name = (updateItem.Name);
if (updateItem.IsDirectory) if (updateItem.IsDirectory)
{ {
item.LinkFlag = NFileHeader::NLinkFlag::kDirectory; item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
item.Size = 0; item.Size = 0;
} }
else else
{ {
item.LinkFlag = NFileHeader::NLinkFlag::kNormal; item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
item.Size = updateItem.Size; item.Size = updateItem.Size;
} }
item.ModificationTime = updateItem.Time; item.ModificationTime = updateItem.Time;
item.DeviceMajorDefined = false; item.DeviceMajorDefined = false;
@@ -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();
} }
}} }}
+96 -99
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
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidSize: prop = m_Database.GetUnpackSize(); break;
case kpidPackedSize: prop = m_Database.GetPackSize(); break;
case kpidIsVolume:
if (m_Xmls.Size() > 0)
{
UInt16 volIndex = m_Xmls[0].VolIndex;
if (volIndex < m_Volumes.Size())
prop = (m_Volumes[volIndex].Header.NumParts > 1);
}
break;
case kpidVolume:
if (m_Xmls.Size() > 0)
{
UInt16 volIndex = m_Xmls[0].VolIndex;
if (volIndex < m_Volumes.Size())
prop = m_Volumes[volIndex].Header.PartNumber;
}
break;
case kpidNumVolumes: if (m_Volumes.Size() > 0) prop = (UInt32)(m_Volumes.Size() - 1);
}
prop.Detach(value);
return S_OK; return S_OK;
} COM_TRY_END
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
return E_INVALIDARG;
const STATPROPSTG &srcItem = kProperties[index];
*propID = srcItem.propid;
*varType = srcItem.vt;
if (srcItem.lpwstrName == 0)
*name = 0;
else
*name = ::SysAllocString(srcItem.lpwstrName);
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{
*numProperties = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_INVALIDARG;
} }
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;
} }
+17
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();
-91
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;
}
+24 -67
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,26 +108,26 @@ 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));
if(!testMode && !realOutStream) if (!testMode && !realOutStream)
return S_OK; return S_OK;
extractCallback->PrepareOperation(askMode); extractCallback->PrepareOperation(askMode);
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)); outStream.Release();
return S_OK; return extractCallback->SetOperationResult(opResult);
COM_TRY_END COM_TRY_END
} }
+33 -75
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))
+4
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;
} }
} }
+1 -1
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
+107 -30
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);
+8
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
+2 -1
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;;
@@ -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);
+1 -1
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:
+1 -1
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"
+4 -4
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"
+2 -4
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)
+1 -1
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"
+12 -12
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"
+5 -13
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
+5 -5
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"
+9 -18
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;
+35 -3
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);
+1 -1
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
+23 -38
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);
} }
+8 -18
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
+1 -1
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;
} }
+15 -1
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;
} }
+1 -1
View File
@@ -40,7 +40,7 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
if (size > *outSize - TotalSize) if (size > *outSize - TotalSize)
size = (UInt32)(*outSize - TotalSize); size = (UInt32)(*outSize - TotalSize);
RINOK(inStream->Read(_buffer, size, &realProcessedSize)); RINOK(inStream->Read(_buffer, size, &realProcessedSize));
if(realProcessedSize == 0) if (realProcessedSize == 0)
break; break;
RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL)); RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
TotalSize += realProcessedSize; TotalSize += realProcessedSize;
+4 -8
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)
+1
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; }
} }
+3 -2
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.
+2 -5
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);
-195
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
-86
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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,3 +0,0 @@
#define IDD_DIALOG_LISTBOX 202
#define IDC_LISTBOX_LIST 1000
@@ -1,22 +0,0 @@
#include "resource.h"
#include "../../../GuiCommon.rc"
#define xSize2 223
#define ySize2 177
#define xSize (xSize2 + marg + marg)
#define ySize (ySize2 + marg + marg)
#define bYPos (ySize - marg - bYSize)
#define b1XPos (xSize - marg - bXSize)
#define b2XPos (b1XPos - 10 - bXSize)
IDD_DIALOG_LISTBOX DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE
CAPTION "List Box"
MY_FONT
BEGIN
LISTBOX IDC_LISTBOX_LIST, marg, marg, xSize2, 149, LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize
PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize
END
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,56 +0,0 @@
#include "resource.h"
#include "../../../GuiCommon.rc"
#define xSize2 290
#define ySize2 76
#define xSize (xSize2 + marg + marg)
#define ySize (ySize2 + marg + marg)
#define bYPos (ySize - marg - bYSize)
#undef bXSize
#define bXSize 72
#define bXPos1 (xSize - marg - bXSize)
#define bXPos2 (bXPos1 - 10 - bXSize)
#define bXPos3 (bXPos2 - 10 - bXSize)
#define valSize 42
#define timeSize 91
#define labelPos 178
#define valPos1 (marg + timeSize)
#define valPos2 (xSize - marg - valSize)
#define labelSize (valPos2 - labelPos)
#undef yPos
#define yPos (marg + 11)
IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
CAPTION "Progress"
MY_FONT
BEGIN
PUSHBUTTON "&Background", IDC_BUTTON_PROGRESS_PRIORITY, bXPos3, bYPos, bXSize, bYSize
PUSHBUTTON "&Pause", IDC_BUTTON_PAUSE, bXPos2, bYPos, bXSize, bYSize
PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize
LTEXT "Elapsed time:", IDC_PROGRESS_ELAPSED, marg, marg, timeSize, 8
LTEXT "Remaining time:", IDC_PROGRESS_REMAINING, marg, yPos, timeSize, 8
LTEXT "Size:", IDC_PROGRESS_TOTAL, labelPos, marg, labelSize, 8
LTEXT "Speed:", IDC_PROGRESS_SPEED, labelPos, yPos, labelSize, 8
RTEXT "00:00:00", IDC_PROGRESS_ELAPSED_VALUE, valPos1, marg, valSize, 8
RTEXT "", IDC_PROGRESS_REMAINING_VALUE, valPos1, yPos, valSize, 8
RTEXT "", IDC_PROGRESS_SPEED_TOTAL_VALUE, valPos2, marg, valSize, 8
RTEXT "", IDC_PROGRESS_SPEED_VALUE, valPos2, yPos, valSize, 8
LTEXT "", IDC_PROGRESS_FILE_NAME, marg, yPos + 16, xSize2, 8, SS_NOPREFIX
CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, marg, bYPos - 20, xSize2, 13
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_PROGRESS_PAUSED "Paused"
IDS_PROGRESS_FOREGROUND "&Foreground"
IDS_PROGRESS_CONTINUE "&Continue"
IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?"
END
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
@@ -1,18 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include "Common/NewHandler.h"
#endif
@@ -1,16 +0,0 @@
// stdafx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#define _WIN32_WINNT 0x0400
// it's for Windows NT supporting (MENUITEMINFOW)
#define WINVER 0x0400
#include <windows.h>
#include <commctrl.h>
#include "Common/NewHandler.h"
#endif
-49
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
+100 -104
View File
@@ -1,104 +1,101 @@
{23170F69-40C1-278A-0000-} {23170F69-40C1-278A-0000-00yy00xx0000}
000000xx0000 IProgress.h 00 IProgress.h
05 IProgress 05 IProgress
01 IFolderArchive.h
05 IArchiveFolder
06 IInFolderArchive
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
0A IOutFolderArchive
0B IFolderArchiveUpdateCallback
0Ñ Agent.h::IArchiveFolderInternal
03 IStream.h
01 ISequentialInStream
02 ISequentialOutStream
03 IInStream
04 IOutStream
06 IStreamGetSize
07 IOutStreamFlush
000300xx0000 IStream.h 04 ICoder.h
01 ISequentialInStream 04 ICompressProgressInfo
02 ISequentialOutStream 05 ICompressCoder
03 IInStream 18 ICompressCoder2
04 IOutStream 20 ICompressSetCoderProperties
06 IStreamGetSize 21 ICompressSetDecoderProperties //
07 IOutStreamFlush 22 ICompressSetDecoderProperties2
23 ICompressWriteCoderProperties
24 ICompressGetInStreamProcessedSize
25 ICompressSetCoderMt
30 ICompressGetSubStreamSize
31 ICompressSetInStream
32 ICompressSetOutStream
33 ICompressSetInStreamSize
34 ICompressSetOutStreamSize
40 ICompressFilter
60 ICompressCodecsInfo
61 ISetCompressCodecsInfo
80 ICryptoProperties
88 ICryptoResetSalt
8C ICryptoResetInitVector
90 ICryptoSetPassword
A0 ICryptoSetCRC
000400xx0000 ICoder.h 05 IPassword.h
04 ICompressProgressInfo 10 ICryptoGetTextPassword
05 ICompressCoder 11 ICryptoGetTextPassword2
18 ICompressCoder2
20 ICompressSetCoderProperties
21 ICompressSetDecoderProperties //
22 ICompressSetDecoderProperties2
23 ICompressWriteCoderProperties
24 ICompressGetInStreamProcessedSize
25 ICompressSetCoderMt
30 ICompressGetSubStreamSize
31 ICompressSetInStream
32 ICompressSetOutStream
33 ICompressSetInStreamSize
34 ICompressSetOutStreamSize
40 ICompressFilter
60 ICompressCodecsInfo
61 ISetCompressCodecsInfo
80 ICryptoProperties
88 ICryptoResetSalt
8C ICryptoResetInitVector
90 ICryptoSetPassword
A0 ICryptoSetCRC
000500xx0000 IPassword.h 06 IArchive.h
10 ICryptoGetTextPassword 03 ISetProperties
11 ICryptoGetTextPassword2
10 IArchiveOpenCallback
20 IArchiveExtractCallback
30 IArchiveOpenVolumeCallback
40 IInArchiveGetStream
50 IArchiveOpenSetSubArchiveName
60 IInArchive
000600xx0000 IArchive.h 80 IArchiveUpdateCallback
82 IArchiveUpdateCallback2
03 ISetProperties A0 IOutArchive
10 IArchiveOpenCallback
20 IArchiveExtractCallback
30 IArchiveOpenVolumeCallback
40 IInArchiveGetStream
50 IArchiveOpenSetSubArchiveName
60 IInArchive
80 IArchiveUpdateCallback
82 IArchiveUpdateCallback2
A0 IOutArchive
000100050001 Agent.h::IArchiveFolderInternal
000100xx0000 IFolderArchive.h
05 IArchiveFolder
06 IInFolderArchive
07 IFileExtractCallback.h::IFolderArchiveExtractCallback
0A IOutFolderArchive
0B IFolderArchiveUpdateCallback
08 IFolder.h
000800xxyy00 FolderInterface.h:: 00 IFolderFolder
01 IEnumProperties
02 IFolderGetTypeID
03 IFolderGetPath
04 IFolderWasChanged
05 // IFolderReload
06 IFolderOperations
07 IFolderGetSystemIconIndex
08 IFolderGetItemFullSize
09 IFolderClone
0A IFolderSetFlatMode
0B IFolderOperationsExtractCallback
00 IFolderFolder
01 IEnumProperties
02 IFolderGetTypeID
03 IFolderGetPath
04 IFolderWasChanged
05 IFolderReload //
0504 IFolderChangeNotify
0505 IFolderSetChangeNotify
050A IFolderExtract //
06 IFolderOperations
0601 IFolderOperationsExtractCallback
0602 IFolderOperationsUpdateCallback //
0603 IFolderOperationsDeleteToRecycleBin //
07 IFolderGetSystemIconIndex
08 IFolderGetItemFullSize
09 IFolderClone
0A IFolderSetFlatMode
000900000000} FolderInterface.h::IFolderManager 09 FolderInterface.h
000900010000} FolderInterface.h::IFolderManagerGetIconPath
00 // old IFolderManager
01 IFolderManager
------------------
{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu {23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu
@@ -110,28 +107,28 @@ Handler GUIDs:
{23170F69-40C1-278A-1000-000110xx0000} {23170F69-40C1-278A-1000-000110xx0000}
01 Zip 01 Zip
02 BZip2 02 BZip2
03 Rar 03 Rar
04 Arj 04 Arj
05 Z 05 Z
06 Lzh 06 Lzh
07 7z 07 7z
08 Cab 08 Cab
09 Nsis 09 Nsis
0A Lzma 0A Lzma
E5 Compound E5 Compound
E6 Wim E6 Wim
E7 Iso E7 Iso
E8 Bkf E8 Bkf
E9 Chm E9 Chm
EA Split EA Split
EB Rpm EB Rpm
EC Deb EC Deb
ED Cpio ED Cpio
EE Tar EE Tar
EF GZip EF GZip
{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle {23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle
{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu {23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu
@@ -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
+1 -5
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)
{ {

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