diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2005-09-21 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:44 +0300 |
commit | d66cf2fcf3cc3667f76f1ea50e8360f1c2813753 (patch) | |
tree | 22ffe1a5473b0e988ab1626a0294e1e1b80ca3ee | |
parent | 31e7b924e826b529aa3ad412730a02ee06959985 (diff) |
4.27 beta
393 files changed, 17299 insertions, 4697 deletions
diff --git a/7zip/Archive/7z/7z.dsp b/7zip/Archive/7z/7z.dsp index 2e05281d..83e48cef 100755 --- a/7zip/Archive/7z/7z.dsp +++ b/7zip/Archive/7z/7z.dsp @@ -496,6 +496,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Windows" diff --git a/7zip/Archive/7z/7zDecode.cpp b/7zip/Archive/7z/7zDecode.cpp index e6dbeefd..2deffc12 100755 --- a/7zip/Archive/7z/7zDecode.cpp +++ b/7zip/Archive/7z/7zDecode.cpp @@ -1,4 +1,4 @@ -// Decode.cpp +// 7zDecode.cpp #include "StdAfx.h" @@ -136,10 +136,10 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) CDecoder::CDecoder(bool multiThread) { - _multiThread = true; - #ifdef _ST_MODE - _multiThread = multiThread; + #ifndef _ST_MODE + multiThread = true; #endif + _multiThread = multiThread; _bindInfoExPrevIsDefinded = false; #ifndef EXCLUDE_COM LoadMethodMap(); diff --git a/7zip/Archive/7z/7zExtract.cpp b/7zip/Archive/7z/7zExtract.cpp index 1fcccfd7..bf827dc0 100755 --- a/7zip/Archive/7z/7zExtract.cpp +++ b/7zip/Archive/7z/7zExtract.cpp @@ -142,7 +142,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, extractCallback->SetTotal(importantTotalUnPacked); - CDecoder decoder(true); + CDecoder decoder( + #ifdef _ST_MODE + false + #else + true + #endif + ); // CDecoder1 decoder; UInt64 currentImportantTotalUnPacked = 0; diff --git a/7zip/Archive/7z/7zFolderInStream.cpp b/7zip/Archive/7z/7zFolderInStream.cpp index 91b39fa9..1b3e2a06 100755 --- a/7zip/Archive/7z/7zFolderInStream.cpp +++ b/7zip/Archive/7z/7zFolderInStream.cpp @@ -79,7 +79,7 @@ HRESULT CFolderInStream::CloseStream() return S_OK; } -STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize = 0; while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0) @@ -87,7 +87,7 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processe if (_fileIsOpen) { UInt32 localProcessedSize; - RINOK(_inStreamWithHash->ReadPart( + RINOK(_inStreamWithHash->Read( ((Byte *)data) + realProcessedSize, size, &localProcessedSize)); if (localProcessedSize == 0) { @@ -109,24 +109,6 @@ STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processe return S_OK; } -STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize = 0; - while (size > 0) - { - UInt32 localProcessedSize; - RINOK(ReadPart(((Byte *)data) + realProcessedSize, size, &localProcessedSize)); - if (localProcessedSize == 0) - break; - size -= localProcessedSize; - realProcessedSize += localProcessedSize; - } - if (processedSize != 0) - *processedSize = realProcessedSize; - return S_OK; -} - - STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value) { *value = 0; diff --git a/7zip/Archive/7z/7zFolderInStream.h b/7zip/Archive/7z/7zFolderInStream.h index 12a2ac07..9a720c8b 100755 --- a/7zip/Archive/7z/7zFolderInStream.h +++ b/7zip/Archive/7z/7zFolderInStream.h @@ -26,7 +26,6 @@ public: CFolderInStream(); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); private: diff --git a/7zip/Archive/7z/7zFolderOutStream.cpp b/7zip/Archive/7z/7zFolderOutStream.cpp index c09271f5..bb770ccc 100755 --- a/7zip/Archive/7z/7zFolderOutStream.cpp +++ b/7zip/Archive/7z/7zFolderOutStream.cpp @@ -91,7 +91,8 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt64(size - realProcessedSize)); UInt32 processedSizeLocal; - RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, numBytesToWrite, &processedSizeLocal)); + RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, + numBytesToWrite, &processedSizeLocal)); _filePos += processedSizeLocal; realProcessedSize += processedSizeLocal; @@ -130,12 +131,6 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, return S_OK; } -STDMETHODIMP CFolderOutStream::WritePart(const void *data, - UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult) { while(_currentIndex < _extractStatuses->Size()) diff --git a/7zip/Archive/7z/7zFolderOutStream.h b/7zip/Archive/7z/7zFolderOutStream.h index 9153070e..c132c79a 100755 --- a/7zip/Archive/7z/7zFolderOutStream.h +++ b/7zip/Archive/7z/7zFolderOutStream.h @@ -22,7 +22,6 @@ public: CFolderOutStream(); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: COutStreamWithCRC *_outStreamWithHashSpec; diff --git a/7zip/Archive/7z/7zHandler.h b/7zip/Archive/7z/7zHandler.h index 7966b86c..b7a53b20 100755 --- a/7zip/Archive/7z/7zHandler.h +++ b/7zip/Archive/7z/7zHandler.h @@ -50,9 +50,9 @@ struct COneMethodInfo }; #endif -// {23170F69-40C1-278A-1000-000110050000} +// {23170F69-40C1-278A-1000-000110070000} DEFINE_GUID(CLSID_CFormat7z, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); class CHandler: public IInArchive, diff --git a/7zip/Archive/7z/7zIn.cpp b/7zip/Archive/7z/7zIn.cpp index 93a72c75..c35a77ce 100755 --- a/7zip/Archive/7z/7zIn.cpp +++ b/7zip/Archive/7z/7zIn.cpp @@ -6,6 +6,7 @@ #include "7zMethods.h" #include "7zDecode.h" #include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" #include "../../../Common/CRC.h" namespace NArchive { @@ -69,7 +70,7 @@ HRESULT CInArchive::ReadDirect(IInStream *stream, void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; - HRESULT result = stream->Read(data, size, &realProcessedSize); + HRESULT result = ReadStream(stream, data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; _position += realProcessedSize; @@ -850,7 +851,13 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(UInt64 baseOffset, // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader; CNum packIndex = 0; - CDecoder decoder(false); + CDecoder decoder( + #ifdef _ST_MODE + false + #else + true + #endif + ); UInt64 dataStartPos = baseOffset + dataOffset; for(int i = 0; i < folders.Size(); i++) { diff --git a/7zip/Archive/7z/7zOut.cpp b/7zip/Archive/7z/7zOut.cpp index b2ba2db3..116cb0cc 100755 --- a/7zip/Archive/7z/7zOut.cpp +++ b/7zip/Archive/7z/7zOut.cpp @@ -11,10 +11,10 @@ static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t { while (size > 0) { - UInt32 curSize = (UInt32)(MyMin(size, (size_t)0xFFFFFFFF)); + UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF); UInt32 processedSize; - RINOK(stream->WritePart(data, curSize, &processedSize)); - if(processedSize == 0 || processedSize > curSize) + RINOK(stream->Write(data, curSize, &processedSize)); + if(processedSize == 0) return E_FAIL; data = (const void *)((const Byte *)data + processedSize); size -= processedSize; @@ -111,7 +111,10 @@ HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker) { SeqStream.QueryInterface(IID_IOutStream, &Stream); if (!Stream) - endMarker = true; + { + return E_NOTIMPL; + // endMarker = true; + } } #ifdef _7Z_VOL if (endMarker) diff --git a/7zip/Archive/7z/7zSpecStream.cpp b/7zip/Archive/7z/7zSpecStream.cpp index fb42d98c..80d303a4 100755 --- a/7zip/Archive/7z/7zSpecStream.cpp +++ b/7zip/Archive/7z/7zSpecStream.cpp @@ -14,16 +14,6 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 return result; } -STDMETHODIMP CSequentialInStreamSizeCount2::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize != 0) - *processedSize = realProcessedSize; - return result; -} - STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize( UInt64 subStream, UInt64 *value) { diff --git a/7zip/Archive/7z/7zSpecStream.h b/7zip/Archive/7z/7zSpecStream.h index 7d3cf538..0253c421 100755 --- a/7zip/Archive/7z/7zSpecStream.h +++ b/7zip/Archive/7z/7zSpecStream.h @@ -28,7 +28,6 @@ public: MY_UNKNOWN_IMP1(ICompressGetSubStreamSize) STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value); }; diff --git a/7zip/Archive/7z/7zUpdate.cpp b/7zip/Archive/7z/7zUpdate.cpp index 5722aba4..e5d82764 100755 --- a/7zip/Archive/7z/7zUpdate.cpp +++ b/7zip/Archive/7z/7zUpdate.cpp @@ -89,11 +89,13 @@ UString CUpdateItem::GetExtension() const return Name.Mid(GetExtensionPos()); } +/* struct CFolderRef { const CArchiveDatabaseEx *Database; int FolderIndex; }; +*/ #define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } @@ -159,31 +161,31 @@ static int CompareFiles(const CFileItem &f1, const CFileItem &f2) return MyStringCollateNoCase(f1.Name, f2.Name); } -static int __cdecl CompareFolderRefs(const void *p1, const void *p2) +static int CompareFolderRefs(const int *p1, const int *p2, void *param) { - const CFolderRef &a1 = *((const CFolderRef *)p1); - const CFolderRef &a2 = *((const CFolderRef *)p2); - const CArchiveDatabaseEx &d1 = *a1.Database; - const CArchiveDatabaseEx &d2 = *a2.Database; + int i1 = *p1; + int i2 = *p2; + const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param; RINOZ(CompareFolders( - d1.Folders[a1.FolderIndex], - d2.Folders[a2.FolderIndex])); + db.Folders[i1], + db.Folders[i2])); RINOZ(MyCompare( - d1.NumUnPackStreamsVector[a1.FolderIndex], - d2.NumUnPackStreamsVector[a2.FolderIndex])); - if (d1.NumUnPackStreamsVector[a1.FolderIndex] == 0) + db.NumUnPackStreamsVector[i1], + db.NumUnPackStreamsVector[i2])); + if (db.NumUnPackStreamsVector[i1] == 0) return 0; return CompareFiles( - d1.Files[d1.FolderStartFileIndex[a1.FolderIndex]], - d2.Files[d2.FolderStartFileIndex[a2.FolderIndex]]); + db.Files[db.FolderStartFileIndex[i1]], + db.Files[db.FolderStartFileIndex[i2]]); } //////////////////////////////////////////////////////////// -static int __cdecl CompareEmptyItems(const void *p1, const void *p2) +static int CompareEmptyItems(const int *p1, const int *p2, void *param) { - const CUpdateItem &u1 = **((CUpdateItem **)p1); - const CUpdateItem &u2 = **((CUpdateItem **)p2); + const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param; + const CUpdateItem &u1 = updateItems[*p1]; + const CUpdateItem &u2 = updateItems[*p2]; if (u1.IsDirectory != u2.IsDirectory) { if (u1.IsDirectory) @@ -234,10 +236,10 @@ struct CRefItem } }; -static int __cdecl CompareUpdateItems(const void *p1, const void *p2) +static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param) { - const CRefItem &a1 = *((CRefItem *)p1); - const CRefItem &a2 = *((CRefItem *)p2); + const CRefItem &a1 = *p1; + const CRefItem &a2 = *p2; const CUpdateItem &u1 = *a1.UpdateItem; const CUpdateItem &u2 = *a2.UpdateItem; int n; @@ -455,7 +457,7 @@ static void FromUpdateItemToFileItem(const CUpdateItem &updateItem, static HRESULT Update2( IInStream *inStream, const CArchiveDatabaseEx *database, - CObjectVector<CUpdateItem> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options) @@ -496,38 +498,32 @@ static HRESULT Update2( fileIndexToUpdateIndexMap[index] = i; } - CRecordVector<CFolderRef> folderRefs; + CRecordVector<int> folderRefs; if (database != 0) { - for(i = 0; i < database->Folders.Size(); i++) - { - CNum indexInFolder = 0; - CNum numCopyItems = 0; - CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; - for (CNum fileIndex = database->FolderStartFileIndex[i]; - indexInFolder < numUnPackStreams; fileIndex++) + for(i = 0; i < database->Folders.Size(); i++) { - if (database->Files[fileIndex].HasStream) + CNum indexInFolder = 0; + CNum numCopyItems = 0; + CNum numUnPackStreams = database->NumUnPackStreamsVector[i]; + for (CNum fileIndex = database->FolderStartFileIndex[i]; + indexInFolder < numUnPackStreams; fileIndex++) { - indexInFolder++; - int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; - if (updateIndex >= 0) - if (!updateItems[updateIndex].NewData) - numCopyItems++; + if (database->Files[fileIndex].HasStream) + { + indexInFolder++; + int updateIndex = fileIndexToUpdateIndexMap[fileIndex]; + if (updateIndex >= 0) + if (!updateItems[updateIndex].NewData) + numCopyItems++; + } } + if (numCopyItems != numUnPackStreams && numCopyItems != 0) + return E_NOTIMPL; // It needs repacking !!! + if (numCopyItems > 0) + folderRefs.Add(i); } - if (numCopyItems != numUnPackStreams && numCopyItems != 0) - return E_NOTIMPL; // It needs repacking !!! - if (numCopyItems > 0) - { - CFolderRef folderRef; - folderRef.Database = database; - folderRef.FolderIndex = i; - folderRefs.Add(folderRef); - } - } - qsort(&folderRefs.Front(), folderRefs.Size(), sizeof(folderRefs[0]), - CompareFolderRefs); + folderRefs.Sort(CompareFolderRefs, (void *)database); } CArchiveDatabase newDatabase; @@ -535,7 +531,7 @@ static HRESULT Update2( ///////////////////////////////////////// // Write Empty Files & Folders - CRecordVector<const CUpdateItem *> emptyRefs; + CRecordVector<int> emptyRefs; for(i = 0; i < updateItems.Size(); i++) { const CUpdateItem &updateItem = updateItems[i]; @@ -548,13 +544,12 @@ static HRESULT Update2( if (updateItem.IndexInArchive != -1) if (database->Files[updateItem.IndexInArchive].HasStream) continue; - emptyRefs.Add(&updateItem); + emptyRefs.Add(i); } - qsort(&emptyRefs.Front(), emptyRefs.Size(), sizeof(emptyRefs[0]), - CompareEmptyItems); + emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems); for(i = 0; i < emptyRefs.Size(); i++) { - const CUpdateItem &updateItem = *emptyRefs[i]; + const CUpdateItem &updateItem = updateItems[emptyRefs[i]]; CFileItem file; if (updateItem.NewProperties) FromUpdateItemToFileItem(updateItem, file); @@ -566,11 +561,11 @@ static HRESULT Update2( //////////////////////////// COutArchive archive; - archive.Create(seqOutStream, false); + RINOK(archive.Create(seqOutStream, false)); RINOK(archive.SkeepPrefixArchiveHeader()); UInt64 complexity = 0; for(i = 0; i < folderRefs.Size(); i++) - complexity += database->GetFolderFullPackSize(folderRefs[i].FolderIndex); + complexity += database->GetFolderFullPackSize(folderRefs[i]); for(i = 0; i < updateItems.Size(); i++) { const CUpdateItem &updateItem = updateItems[i]; @@ -586,7 +581,7 @@ static HRESULT Update2( for(i = 0; i < folderRefs.Size(); i++) { - int folderIndex = folderRefs[i].FolderIndex; + int folderIndex = folderRefs[i]; RINOK(WriteRange(inStream, archive.SeqStream, database->GetFolderStreamPos(folderIndex, 0), @@ -652,7 +647,7 @@ static HRESULT Update2( for (i = 0; i < numFiles; i++) refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], numSolidFiles > 1)); - qsort(&refItems.Front(), refItems.Size(), sizeof(refItems[0]), CompareUpdateItems); + refItems.Sort(CompareUpdateItems, 0); CRecordVector<UInt32> indices; indices.Reserve(numFiles); @@ -862,7 +857,7 @@ HRESULT UpdateVolume( RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream)); COutArchive archive; - archive.Create(volumeStream, true); + RINOK(archive.Create(volumeStream, true)); RINOK(archive.SkeepPrefixArchiveHeader()); CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC; @@ -914,7 +909,6 @@ public: HRESULT Flush(); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; HRESULT COutVolumeStream::Flush() @@ -943,7 +937,7 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream)); _volIndex++; _curPos = 0; - _archive.Create(_volumeStream, true); + RINOK(_archive.Create(_volumeStream, true)); RINOK(_archive.SkeepPrefixArchiveHeader()); _crc.Init(); continue; @@ -959,7 +953,7 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc if(processedSize != NULL) *processedSize += realProcessed; _curPos += realProcessed; - if (realProcessed != curSize) + if (realProcessed != curSize && realProcessed == 0) return E_FAIL; if (_curPos == pureSize) { @@ -969,16 +963,12 @@ STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *proc return S_OK; } -STDMETHODIMP COutVolumeStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} #endif HRESULT Update( IInStream *inStream, const CArchiveDatabaseEx *database, - CObjectVector<CUpdateItem> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options) diff --git a/7zip/Archive/7z/7zUpdate.h b/7zip/Archive/7z/7zUpdate.h index ab6cff4f..7567864a 100755 --- a/7zip/Archive/7z/7zUpdate.h +++ b/7zip/Archive/7z/7zUpdate.h @@ -60,7 +60,7 @@ struct CUpdateOptions HRESULT Update( IInStream *inStream, const CArchiveDatabaseEx *database, - CObjectVector<CUpdateItem> &updateItems, + const CObjectVector<CUpdateItem> &updateItems, ISequentialOutStream *seqOutStream, IArchiveUpdateCallback *updateCallback, const CUpdateOptions &options); diff --git a/7zip/Archive/7z/makefile b/7zip/Archive/7z/makefile index 5c58e960..97bbbaaf 100755 --- a/7zip/Archive/7z/makefile +++ b/7zip/Archive/7z/makefile @@ -48,6 +48,7 @@ WIN_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CodecsPath.obj \ diff --git a/7zip/Archive/7z_C/makefile.gcc b/7zip/Archive/7z_C/makefile.gcc new file mode 100755 index 00000000..21b7df47 --- /dev/null +++ b/7zip/Archive/7z_C/makefile.gcc @@ -0,0 +1,50 @@ +PROG = 7zDec +CXX = g++ +LIB = +RM = rm -f +CFLAGS = -c -O2 -Wall + +OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o + +all: $(PROG) + +$(PROG): $(OBJS) + $(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) + +7zAlloc.o: 7zAlloc.c + $(CXX) $(CFLAGS) 7zAlloc.c + +7zBuffer.o: 7zBuffer.c + $(CXX) $(CFLAGS) 7zBuffer.c + +7zCrc.o: 7zCrc.c + $(CXX) $(CFLAGS) 7zCrc.c + +7zDecode.o: 7zDecode.c + $(CXX) $(CFLAGS) 7zDecode.c + +7zExtract.o: 7zExtract.c + $(CXX) $(CFLAGS) 7zExtract.c + +7zHeader.o: 7zHeader.c + $(CXX) $(CFLAGS) 7zHeader.c + +7zIn.o: 7zIn.c + $(CXX) $(CFLAGS) 7zIn.c + +7zItem.o: 7zItem.c + $(CXX) $(CFLAGS) 7zItem.c + +7zMain.o: 7zMain.c + $(CXX) $(CFLAGS) 7zMain.c + +7zMethodID.o: 7zMethodID.c + $(CXX) $(CFLAGS) 7zMethodID.c + +LzmaDecode.o: ../../Compress/LZMA_C/LzmaDecode.c + $(CXX) $(CFLAGS) ../../Compress/LZMA_C/LzmaDecode.c + + +clean: + -$(RM) $(PROG) $(OBJS) + diff --git a/7zip/Archive/Arj/Arj.dsp b/7zip/Archive/Arj/Arj.dsp index 0963ce38..3bc6fa91 100755 --- a/7zip/Archive/Arj/Arj.dsp +++ b/7zip/Archive/Arj/Arj.dsp @@ -213,19 +213,19 @@ SOURCE=.\ArjItem.h # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\Arj\Decoder1.cpp +SOURCE=..\..\Compress\Arj\ArjDecoder1.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\Arj\Decoder1.h +SOURCE=..\..\Compress\Arj\ArjDecoder1.h # End Source File # Begin Source File -SOURCE=..\..\Compress\Arj\Decoder2.cpp +SOURCE=..\..\Compress\Arj\ArjDecoder2.cpp # End Source File # Begin Source File -SOURCE=..\..\Compress\Arj\Decoder2.h +SOURCE=..\..\Compress\Arj\ArjDecoder2.h # End Source File # End Group # Begin Group "LZ" @@ -278,12 +278,28 @@ SOURCE=..\..\Common\MSBFDecoder.h # End Source File # Begin Source File +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\ProgressUtils.cpp # End Source File # Begin Source File SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Archive Common" diff --git a/7zip/Archive/Arj/ArjHandler.cpp b/7zip/Archive/Arj/ArjHandler.cpp index 7701da3b..ab75493f 100755 --- a/7zip/Archive/Arj/ArjHandler.cpp +++ b/7zip/Archive/Arj/ArjHandler.cpp @@ -19,8 +19,8 @@ #include "../../Common/LimitedStreams.h" #include "../../Compress/Copy/CopyCoder.h" -#include "../../Compress/Arj/Decoder1.h" -#include "../../Compress/Arj/Decoder2.h" +#include "../../Compress/Arj/ArjDecoder1.h" +#include "../../Compress/Arj/ArjDecoder2.h" #include "../Common/ItemNameUtils.h" #include "../Common/OutStreamWithCRC.h" diff --git a/7zip/Archive/Arj/ArjIn.cpp b/7zip/Archive/Arj/ArjIn.cpp index c019055c..03346824 100755 --- a/7zip/Archive/Arj/ArjIn.cpp +++ b/7zip/Archive/Arj/ArjIn.cpp @@ -6,6 +6,8 @@ #include "Common/Buffer.h" #include "Common/CRC.h" +#include "../../Common/StreamUtils.h" + #include "ArjIn.h" namespace NArchive { @@ -14,7 +16,7 @@ namespace NArj { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); + HRESULT result = ReadStream(_stream, data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; IncreasePositionValue(realProcessedSize); @@ -162,7 +164,7 @@ bool CInArchive::ReadBlock() { _blockPos = 0; _blockSize = SafeReadUInt16(); - if (_blockSize == 0) + if (_blockSize == 0 || _blockSize > kMaxBlockSize) return false; SafeReadBytes(_block, _blockSize); UInt32 crcFromFile = SafeReadUInt32(); diff --git a/7zip/Archive/Arj/DllExports.cpp b/7zip/Archive/Arj/DllExports.cpp index abedc1f7..202fbe0d 100755 --- a/7zip/Archive/Arj/DllExports.cpp +++ b/7zip/Archive/Arj/DllExports.cpp @@ -8,9 +8,9 @@ #include "../../ICoder.h" #include "ArjHandler.h" -// {23170F69-40C1-278A-1000-0001100A0000} +// {23170F69-40C1-278A-1000-000110040000} DEFINE_GUID(CLSID_CArjHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0A, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/Arj/makefile b/7zip/Archive/Arj/makefile index d45975b4..2609998b 100755 --- a/7zip/Archive/Arj/makefile +++ b/7zip/Archive/Arj/makefile @@ -22,15 +22,17 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\InBuffer.obj \ $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\ItemNameUtils.obj \ $O\OutStreamWithCRC.obj \ COMPRESS_ARJ_OBJS = \ - $O\Decoder1.obj \ - $O\Decoder2.obj \ + $O\ArjDecoder1.obj \ + $O\ArjDecoder2.obj \ OBJS = \ $O\StdAfx.obj \ diff --git a/7zip/Archive/BZip2/BZip2.dsp b/7zip/Archive/BZip2/BZip2.dsp index 0e28884f..ccae8d3b 100755 --- a/7zip/Archive/BZip2/BZip2.dsp +++ b/7zip/Archive/BZip2/BZip2.dsp @@ -256,6 +256,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Source File diff --git a/7zip/Archive/BZip2/BZip2Handler.cpp b/7zip/Archive/BZip2/BZip2Handler.cpp index 97ea155c..88e5da1f 100755 --- a/7zip/Archive/BZip2/BZip2Handler.cpp +++ b/7zip/Archive/BZip2/BZip2Handler.cpp @@ -7,7 +7,7 @@ #include "Common/Defs.h" #include "../../Common/ProgressUtils.h" -// #include "Interface/EnumStatProp.h" +#include "../../Common/StreamUtils.h" #include "Windows/PropVariant.h" #include "Windows/Defs.h" @@ -111,7 +111,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, const int kSignatureSize = 3; Byte buffer[kSignatureSize]; UInt32 processedSize; - RINOK(stream->Read(buffer, kSignatureSize, &processedSize)); + RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize)); if (processedSize != kSignatureSize) return S_FALSE; if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h') @@ -221,7 +221,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, const int kSignatureSize = 3; Byte buffer[kSignatureSize]; UInt32 processedSize; - RINOK(_stream->Read(buffer, kSignatureSize, &processedSize)); + RINOK(ReadStream(_stream, buffer, kSignatureSize, &processedSize)); if (processedSize < kSignatureSize) { if (firstItem) diff --git a/7zip/Archive/BZip2/DllExports.cpp b/7zip/Archive/BZip2/DllExports.cpp index 52e9cca4..932a75bb 100755 --- a/7zip/Archive/BZip2/DllExports.cpp +++ b/7zip/Archive/BZip2/DllExports.cpp @@ -16,9 +16,9 @@ DEFINE_GUID(CLSID_CCompressBZip2Encoder, DEFINE_GUID(CLSID_CCompressBZip2Decoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); -// {23170F69-40C1-278A-1000-000110070000} +// {23170F69-40C1-278A-1000-000110020000} DEFINE_GUID(CLSID_CBZip2Handler, -0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00); HINSTANCE g_hInstance; diff --git a/7zip/Archive/BZip2/makefile b/7zip/Archive/BZip2/makefile index 936abdcc..85095122 100755 --- a/7zip/Archive/BZip2/makefile +++ b/7zip/Archive/BZip2/makefile @@ -22,6 +22,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CodecsPath.obj \ diff --git a/7zip/Archive/Cab/Cab.dsp b/7zip/Archive/Cab/Cab.dsp index f96be2e0..565661f6 100755 --- a/7zip/Archive/Cab/Cab.dsp +++ b/7zip/Archive/Cab/Cab.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /c -# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAs /Yu"StdAfx.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "NDEBUG" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CAB_EXPORTS" /FAcs /Yu"StdAfx.h" /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x419 /d "_DEBUG" @@ -190,11 +190,11 @@ SOURCE=..\..\..\Windows\PropVariant.h # PROP Default_Filter "" # Begin Source File -SOURCE=.\CabCopyDecoder.cpp +SOURCE=.\CabBlockInStream.cpp # End Source File # Begin Source File -SOURCE=.\CabCopyDecoder.h +SOURCE=.\CabBlockInStream.h # End Source File # Begin Source File @@ -222,110 +222,168 @@ SOURCE=.\CabIn.h # End Source File # Begin Source File -SOURCE=.\CabInBuffer.cpp +SOURCE=.\CabItem.h # End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\CabInBuffer.h +SOURCE=..\..\Common\InBuffer.cpp # End Source File # Begin Source File -SOURCE=.\CabItem.h +SOURCE=..\..\Common\InBuffer.h # End Source File # Begin Source File -SOURCE=.\LZXBitDecoder.h +SOURCE=..\..\Common\LSBFDecoder.cpp # End Source File # Begin Source File -SOURCE=.\LZXConst.h +SOURCE=..\..\Common\LSBFDecoder.h # End Source File # Begin Source File -SOURCE=.\LZXDecoder.cpp +SOURCE=..\..\Common\MSBFDecoder.h # End Source File # Begin Source File -SOURCE=.\LZXDecoder.h +SOURCE=..\..\Common\OutBuffer.cpp # End Source File # Begin Source File -SOURCE=.\LZXExtConst.h +SOURCE=..\..\Common\OutBuffer.h # End Source File # Begin Source File -SOURCE=.\LZXi86Converter.cpp +SOURCE=..\..\Common\StreamUtils.cpp # End Source File # Begin Source File -SOURCE=.\LZXi86Converter.h +SOURCE=..\..\Common\StreamUtils.h # End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\MSZipConst.h +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp # End Source File # Begin Source File -SOURCE=.\MSZipDecoder.cpp +SOURCE=..\..\Compress\LZ\LZOutWindow.h # End Source File +# End Group +# Begin Group "Lzx" + +# PROP Default_Filter "" # Begin Source File -SOURCE=.\MSZipDecoder.h +SOURCE=..\..\Compress\Lzx\Lzx.h # End Source File # Begin Source File -SOURCE=.\MSZipExtConst.h +SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp + +!IF "$(CFG)" == "Cab - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +!ENDIF + # End Source File -# End Group -# Begin Group "7zip Common" +# Begin Source File -# PROP Default_Filter "" +SOURCE=..\..\Compress\Lzx\Lzx86Converter.h +# End Source File # Begin Source File -SOURCE=..\..\Common\InBuffer.cpp +SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp + +!IF "$(CFG)" == "Cab - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +!ENDIF + # End Source File # Begin Source File -SOURCE=..\..\Common\InBuffer.h +SOURCE=..\..\Compress\Lzx\LzxDecoder.h # End Source File +# End Group +# Begin Group "Deflate" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Common\LSBFDecoder.cpp +SOURCE=..\..\Compress\Deflate\DeflateConst.h # End Source File # Begin Source File -SOURCE=..\..\Common\LSBFDecoder.h +SOURCE=..\..\Compress\Deflate\DeflateDecoder.cpp + +!IF "$(CFG)" == "Cab - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Cab - Win32 Debug" + +!ENDIF + # End Source File # Begin Source File -SOURCE=..\..\Common\OutBuffer.cpp +SOURCE=..\..\Compress\Deflate\DeflateDecoder.h # End Source File # Begin Source File -SOURCE=..\..\Common\OutBuffer.h +SOURCE=..\..\Compress\Deflate\DeflateExtConst.h # End Source File +# End Group +# Begin Group "Copy" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Common\ProgressUtils.cpp +SOURCE=..\..\Compress\Copy\CopyCoder.cpp # End Source File # Begin Source File -SOURCE=..\..\Common\ProgressUtils.h +SOURCE=..\..\Compress\Copy\CopyCoder.h # End Source File # End Group -# Begin Group "Compress" +# Begin Group "Quantum" # PROP Default_Filter "" -# Begin Group "LZ" +# Begin Source File -# PROP Default_Filter "" +SOURCE=..\..\Compress\Quantum\QuantumDecoder.cpp +# End Source File # Begin Source File -SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +SOURCE=..\..\Compress\Quantum\QuantumDecoder.h # End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Compress\LZ\LZOutWindow.h +SOURCE=..\..\Compress\Huffman\HuffmanDecoder.h # End Source File # End Group # End Group diff --git a/7zip/Archive/Cab/CabBlockInStream.cpp b/7zip/Archive/Cab/CabBlockInStream.cpp new file mode 100755 index 00000000..b775c105 --- /dev/null +++ b/7zip/Archive/Cab/CabBlockInStream.cpp @@ -0,0 +1,194 @@ +// CabBlockInStream.cpp + +#include "StdAfx.h" + +#include "Common/Alloc.h" +#include "Common/Defs.h" + +#include "../../Common/StreamUtils.h" + +#include "CabBlockInStream.h" + +namespace NArchive { +namespace NCab { + +static const UInt32 kBlockSize = (1 << 16); + +bool CCabBlockInStream::Create() +{ + if (!_buffer) + _buffer = (Byte *)::MyAlloc(kBlockSize); + return (_buffer != 0); +} + +CCabBlockInStream::~CCabBlockInStream() +{ + MyFree(_buffer); +} + +class CCheckSum2 +{ + UInt32 m_Value; + int m_Pos; + Byte m_Hist[4]; +public: + CCheckSum2(): m_Value(0){}; + void Init() { m_Value = 0; m_Pos = 0; } + void Update(const void *data, UInt32 size); + void FinishDataUpdate() + { + for (int i = 0; i < m_Pos; i++) + m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1)); + } + void UpdateUInt32(UInt32 v) { m_Value ^= v; } + UInt32 GetResult() const { return m_Value; } +}; + +void CCheckSum2::Update(const void *data, UInt32 size) +{ + UInt32 checkSum = m_Value; + const Byte *dataPointer = (const Byte *)data; + + while (size != 0 && m_Pos != 0) + { + m_Hist[m_Pos] = *dataPointer++; + m_Pos = (m_Pos + 1) & 3; + size--; + if (m_Pos == 0) + for (int i = 0; i < 4; i++) + checkSum ^= ((UInt32)m_Hist[i]) << (8 * i); + } + + int numWords = size / 4; + + while (numWords-- != 0) + { + UInt32 temp = *dataPointer++; + temp |= ((UInt32)(*dataPointer++)) << 8; + temp |= ((UInt32)(*dataPointer++)) << 16; + temp |= ((UInt32)(*dataPointer++)) << 24; + checkSum ^= temp; + } + m_Value = checkSum; + + size &= 3; + + while (size != 0) + { + m_Hist[m_Pos] = *dataPointer++; + m_Pos = (m_Pos + 1) & 3; + size--; + } +} + +static const UInt32 kDataBlockHeaderSize = 8; + +class CTempCabInBuffer2 +{ +public: + Byte Buffer[kDataBlockHeaderSize]; + UInt32 Pos; + Byte ReadByte() + { + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + UInt16 ReadUInt16() + { + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= (((UInt16)ReadByte()) << (8 * i)); + return value; + } +}; + +HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize) +{ + CTempCabInBuffer2 inBuffer; + inBuffer.Pos = 0; + UInt32 processedSizeLoc; + RINOK(ReadStream(_stream, inBuffer.Buffer, kDataBlockHeaderSize, &processedSizeLoc)) + if (processedSizeLoc != kDataBlockHeaderSize) + return S_FALSE; // bad block + + UInt32 checkSum = inBuffer.ReadUInt32(); + packSize = inBuffer.ReadUInt16(); + unpackSize = inBuffer.ReadUInt16(); + if (ReservedSize != 0) + { + RINOK(ReadStream(_stream, _buffer, ReservedSize, &processedSizeLoc)); + if(ReservedSize != processedSizeLoc) + return S_FALSE; // bad block; + } + _pos = 0; + CCheckSum2 checkSumCalc; + checkSumCalc.Init(); + UInt32 packSize2 = packSize; + if (MsZip && _size == 0) + { + if (packSize < 2) + return S_FALSE; // bad block; + Byte sig[2]; + RINOK(ReadStream(_stream, sig, 2, &processedSizeLoc)); + if(processedSizeLoc != 2) + return S_FALSE; + if (sig[0] != 0x43 || sig[1] != 0x4B) + return S_FALSE; + packSize2 -= 2; + checkSumCalc.Update(sig, 2); + } + + if (kBlockSize - _size < packSize2) + return S_FALSE; + + UInt32 curSize = packSize2; + if (curSize != 0) + { + RINOK(ReadStream(_stream, _buffer + _size, curSize, &processedSizeLoc)); + checkSumCalc.Update(_buffer + _size, processedSizeLoc); + _size += processedSizeLoc; + if (processedSizeLoc != curSize) + return S_FALSE; + } + TotalPackSize = _size; + + checkSumCalc.FinishDataUpdate(); + + bool dataError; + if (checkSum == 0) + dataError = false; + else + { + checkSumCalc.UpdateUInt32(packSize | (((UInt32)unpackSize) << 16)); + dataError = (checkSumCalc.GetResult() != checkSum); + } + DataError |= dataError; + return dataError ? S_FALSE : S_OK; +} + +STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + if (size == 0) + return S_OK; + if (_size != 0) + { + size = MyMin(_size, size); + memmove(data, _buffer + _pos, size); + _pos += size; + _size -= size; + if (processedSize != 0) + *processedSize = size; + return S_OK; + } + return S_OK; // no blocks data +} + +}} diff --git a/7zip/Archive/Cab/CabBlockInStream.h b/7zip/Archive/Cab/CabBlockInStream.h new file mode 100755 index 00000000..46e15222 --- /dev/null +++ b/7zip/Archive/Cab/CabBlockInStream.h @@ -0,0 +1,56 @@ +// CabBlockInStream.cpp + +#ifndef __CABBLOCKINSTREAM_H +#define __CABBLOCKINSTREAM_H + +#include "Common/MyCom.h" +#include "../../IStream.h" + +namespace NArchive { +namespace NCab { + +class CCabBlockInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CMyComPtr<ISequentialInStream> _stream; + Byte *_buffer; + UInt32 _pos; + UInt32 _size; + int _align; + +public: + UInt32 TotalPackSize; + UInt32 ReservedSize; + bool DataError; + bool MsZip; + + CCabBlockInStream(): _buffer(0), ReservedSize(0), MsZip(false), DataError(false), _align(0), TotalPackSize(0) {} + ~CCabBlockInStream(); + bool Create(); + void SetStream(ISequentialInStream *stream) { _stream = stream; } + + void InitForNewFolder() + { + _align = 0; + TotalPackSize = 0; + } + + void InitForNewBlock() + { + _size = 0; + _align = (_align + (int)TotalPackSize) & 1; + } + + int GetAlign() const { return _align; } + + MY_UNKNOWN_IMP + + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + + HRESULT PreRead(UInt32 &packSize, UInt32 &unpackSize); +}; + +}} + +#endif diff --git a/7zip/Archive/Cab/CabCopyDecoder.cpp b/7zip/Archive/Cab/CabCopyDecoder.cpp deleted file mode 100755 index 541d4d93..00000000 --- a/7zip/Archive/Cab/CabCopyDecoder.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// CabCopyDecoder.cpp - -#include "StdAfx.h" - -#include "CabCopyDecoder.h" -#include "Common/Defs.h" -#include "Windows/Defs.h" - -namespace NArchive { -namespace NCab { - -static const UInt32 kBufferSize = 1 << 17; - -void CCopyDecoder::ReleaseStreams() -{ - m_InStream.ReleaseStream(); - m_OutStream.ReleaseStream(); -} - -class CCopyDecoderFlusher -{ - CCopyDecoder *m_Decoder; -public: - CCopyDecoderFlusher(CCopyDecoder *decoder): m_Decoder(decoder) {} - ~CCopyDecoderFlusher() - { - m_Decoder->Flush(); - m_Decoder->ReleaseStreams(); - } -}; - -STDMETHODIMP CCopyDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - if (outSize == NULL) - return E_INVALIDARG; - UInt64 size = *outSize; - - if (!m_OutStream.Create(1 << 20)) - return E_OUTOFMEMORY; - if (!m_InStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_InStream.SetStream(inStream); - m_InStream.Init(m_ReservedSize, m_NumInDataBlocks); - m_OutStream.SetStream(outStream); - m_OutStream.Init(); - CCopyDecoderFlusher decoderFlusher(this); - - UInt64 nowPos64 = 0; - while(nowPos64 < size) - { - UInt32 blockSize; - bool dataAreCorrect; - RINOK(m_InStream.ReadBlock(blockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw 123456; - } - for (UInt32 i = 0; i < blockSize; i++) - m_OutStream.WriteByte(m_InStream.ReadByte()); - nowPos64 += blockSize; - if (progress != NULL) - { - RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64)); - } - } - return S_OK; -} - -}} diff --git a/7zip/Archive/Cab/CabCopyDecoder.h b/7zip/Archive/Cab/CabCopyDecoder.h deleted file mode 100755 index 21545d39..00000000 --- a/7zip/Archive/Cab/CabCopyDecoder.h +++ /dev/null @@ -1,41 +0,0 @@ -// CabCopyDecoder.h - -#ifndef __ARCHIVE_CAB_COPY_DECODER_H -#define __ARCHIVE_CAB_COPY_DECODER_H - -#include "Common/MyCom.h" -#include "../../ICoder.h" -#include "../../Common/OutBuffer.h" -#include "CabInBuffer.h" - -namespace NArchive { -namespace NCab { - -class CCopyDecoder: - public ICompressCoder, - public CMyUnknownImp -{ - CInBuffer m_InStream; - COutBuffer m_OutStream; - Byte m_ReservedSize; - UInt32 m_NumInDataBlocks; -public: - MY_UNKNOWN_IMP - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - void ReleaseStreams(); - HRESULT Flush() { return m_OutStream.Flush(); } - void SetParams(Byte reservedSize, UInt32 numInDataBlocks) - { - m_ReservedSize = reservedSize; - m_NumInDataBlocks = numInDataBlocks; - } - -}; - -}} - -#endif
\ No newline at end of file diff --git a/7zip/Archive/Cab/CabHandler.cpp b/7zip/Archive/Cab/CabHandler.cpp index 669de218..c3dd061f 100755 --- a/7zip/Archive/Cab/CabHandler.cpp +++ b/7zip/Archive/Cab/CabHandler.cpp @@ -1,9 +1,10 @@ -// Cab/Handler.cpp +// CabHandler.cpp #include "StdAfx.h" #include "Common/StringConvert.h" #include "Common/Defs.h" +#include "Common/Alloc.h" #include "Common/UTFConvert.h" #include "Common/ComTry.h" #include "Common/IntToString.h" @@ -11,32 +12,45 @@ #include "Windows/PropVariant.h" #include "Windows/Time.h" -#include "CabCopyDecoder.h" -#include "LZXDecoder.h" -#include "MSZipDecoder.h" - #include "CabHandler.h" +#include "CabBlockInStream.h" -#include "../../Common/ProgressUtils.h" +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Deflate/DeflateDecoder.h" +#include "../../Compress/Lzx/LzxDecoder.h" +#include "../../Compress/Quantum/QuantumDecoder.h" using namespace NWindows; -using namespace NTime; namespace NArchive { namespace NCab { +// #define _CAB_DETAILS + +#ifdef _CAB_DETAILS +enum +{ + kpidBlockReal = kpidUserDefined, + kpidOffset, + kpidVolume, +}; +#endif + STATPROPSTG kProperties[] = { { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsFolder, VT_BOOL}, + // { NULL, kpidIsFolder, VT_BOOL}, { NULL, kpidSize, VT_UI8}, { NULL, kpidLastWriteTime, VT_FILETIME}, { NULL, kpidAttributes, VT_UI4}, - { NULL, kpidMethod, VT_BSTR}, - // { NULL, kpidDictionarySize, VT_UI4}, - - { NULL, kpidBlock, VT_UI4} + { NULL, kpidBlock, VT_I4} + #ifdef _CAB_DETAILS + , + { L"BlockReal", kpidBlockReal, VT_UI4}, + { L"Offset", kpidOffset, VT_UI4}, + { L"Volume", kpidVolume, VT_UI4} + #endif }; static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]); @@ -72,7 +86,10 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, const STATPROPSTG &srcItem = kProperties[index]; *propID = srcItem.propid; *varType = srcItem.vt; - *name = 0; + if (srcItem.lpwstrName == 0) + *name = 0; + else + *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } @@ -92,31 +109,35 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va { COM_TRY_BEGIN NWindows::NCOM::CPropVariant propVariant; - const CItem &fileInfo = m_Files[index]; + + const CMvItem &mvItem = m_Database.Items[index]; + const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; + int itemIndex = mvItem.ItemIndex; + const CItem &item = db.Items[itemIndex]; switch(propID) { case kpidPath: - if (fileInfo.IsNameUTF()) + if (item.IsNameUTF()) { UString unicodeName; - if (!ConvertUTF8ToUnicode(fileInfo.Name, unicodeName)) + if (!ConvertUTF8ToUnicode(item.Name, unicodeName)) propVariant = L""; else propVariant = unicodeName; } else - propVariant = MultiByteToUnicodeString(fileInfo.Name, CP_ACP); + propVariant = MultiByteToUnicodeString(item.Name, CP_ACP); break; case kpidIsFolder: - propVariant = fileInfo.IsDirectory(); + propVariant = item.IsDirectory(); break; case kpidSize: - propVariant = fileInfo.UnPackSize; + propVariant = item.Size; break; case kpidLastWriteTime: { FILETIME localFileTime, utcFileTime; - if (DosTimeToFileTime(fileInfo.Time, localFileTime)) + if (NTime::DosTimeToFileTime(item.Time, localFileTime)) { if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime)) utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0; @@ -127,21 +148,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va break; } case kpidAttributes: - propVariant = fileInfo.GetWinAttributes(); + propVariant = item.GetWinAttributes(); break; case kpidMethod: { - UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( - m_Folders.Size(), fileInfo.FolderIndex); - const NHeader::CFolder &folder = m_Folders[realFolderIndex]; - UString method; + UInt16 realFolderIndex = item.GetFolderIndex(db.Folders.Size()); + const CFolder &folder = db.Folders[realFolderIndex]; int methodIndex = folder.GetCompressionMethod(); - if (methodIndex < kNumMethods) - method = kMethods[methodIndex]; - else - method = kUnknownMethod; - if (methodIndex == NHeader::NCompressionMethodMajor::kLZX) + UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod; + if (methodIndex == NHeader::NCompressionMethodMajor::kLZX || + methodIndex == NHeader::NCompressionMethodMajor::kQuantum) { method += L":"; wchar_t temp[32]; @@ -152,14 +169,29 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va break; } case kpidBlock: - propVariant = UInt32(fileInfo.FolderIndex); + propVariant = (Int32)m_Database.GetFolderIndex(&mvItem); break; + + #ifdef _CAB_DETAILS + + case kpidBlockReal: + propVariant = UInt32(item.FolderIndex); + break; + case kpidOffset: + propVariant = (UInt32)item.Offset; + break; + case kpidVolume: + propVariant = (UInt32)mvItem.VolumeIndex; + break; + + #endif } propVariant.Detach(value); return S_OK; COM_TRY_END } +/* class CPropgressImp: public CProgressVirt { CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; @@ -183,36 +215,113 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); return S_OK; } +*/ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) { COM_TRY_BEGIN - m_Stream.Release(); - // try + Close(); + HRESULT res; + CInArchive archive; + CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; { - CInArchive archive; - m_Files.Clear(); - CPropgressImp progressImp; - progressImp.Init(openArchiveCallback); - RINOK(archive.Open(inStream, maxCheckStartPosition, - m_ArchiveInfo, m_Folders, m_Files, &progressImp)); - m_Stream = inStream; + CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback; + openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback); + } + + CMyComPtr<IInStream> nextStream = inStream; + bool prevChecked = false; + UInt64 numItems = 0; + try + { + while(nextStream != 0) + { + CDatabaseEx db; + db.Stream = nextStream; + res = archive.Open(maxCheckStartPosition, db); + if (res == S_OK) + { + if (!m_Database.Volumes.IsEmpty()) + { + const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0]; + if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID || + dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) != + db.ArchiveInfo.CabinetNumber) + res = S_FALSE; + } + } + if (res == S_OK) + m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db); + else if (res != S_FALSE) + return res; + else + { + if (m_Database.Volumes.IsEmpty()) + return S_FALSE; + if (prevChecked) + break; + prevChecked = true; + } + + numItems += db.Items.Size(); + RINOK(openArchiveCallback->SetCompleted(&numItems, NULL)); + + nextStream = 0; + while(true) + { + const COtherArchive *otherArchive = 0; + if (!prevChecked) + { + const CInArchiveInfo &ai = m_Database.Volumes.Front().ArchiveInfo; + if (ai.IsTherePrev()) + otherArchive = &ai.PreviousArchive; + else + prevChecked = true; + } + if (otherArchive == 0) + { + const CInArchiveInfo &ai = m_Database.Volumes.Back().ArchiveInfo; + if (ai.IsThereNext()) + otherArchive = &ai.NextArchive; + } + if (!otherArchive) + break; + const UString fullName = MultiByteToUnicodeString(otherArchive->FileName, CP_ACP); + HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); + if (result == S_OK) + break; + if (result != S_FALSE) + return result; + if (prevChecked) + break; + prevChecked = true; + } + } + if (res == S_OK) + { + m_Database.FillSortAndShrink(); + if (!m_Database.Check()) + res = S_FALSE; + } } - /* catch(...) { - return S_FALSE; + res = S_FALSE; + } + if (res != S_OK) + { + Close(); + return res; } - */ COM_TRY_END return S_OK; } STDMETHODIMP CHandler::Close() { - m_Stream.Release(); + m_Database.Clear(); return S_OK; } @@ -224,405 +333,472 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: - const CObjectVector<NHeader::CFolder> *m_Folders; - const CObjectVector<CItem> *m_Files; - const CRecordVector<int> *m_FileIndexes; + const CMvDatabaseEx *m_Database; const CRecordVector<bool> *m_ExtractStatuses; int m_StartIndex; int m_CurrentIndex; - int m_NumFiles; - UInt64 m_CurrentDataPos; CMyComPtr<IArchiveExtractCallback> m_ExtractCallback; bool m_TestMode; + CMyComPtr<ISequentialOutStream> m_RealOutStream; + + bool m_IsOk; bool m_FileIsOpen; - CMyComPtr<ISequentialOutStream> realOutStream; - UInt64 m_FilePos; + UInt64 m_RemainFileSize; + UInt64 m_FolderSize; + UInt64 m_PosInFolder; - HRESULT OpenFile(int indexIndex, ISequentialOutStream **realOutStream); - HRESULT WriteEmptyFiles(); - UInt64 m_StartImportantTotalUnPacked; + HRESULT OpenFile(); + HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); public: + HRESULT WriteEmptyFiles(); + void Init( - const CObjectVector<NHeader::CFolder> *folders, - const CObjectVector<CItem> *files, - const CRecordVector<int> *fileIndices, + const CMvDatabaseEx *database, const CRecordVector<bool> *extractStatuses, int startIndex, - int numFiles, + UInt64 folderSize, IArchiveExtractCallback *extractCallback, - UInt64 startImportantTotalUnPacked, bool testMode); HRESULT FlushCorrupted(); HRESULT Unsupported(); + + UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; } + UInt64 GetPosInFolder() const { return m_PosInFolder; } }; void CCabFolderOutStream::Init( - const CObjectVector<NHeader::CFolder> *folders, - const CObjectVector<CItem> *files, - const CRecordVector<int> *fileIndices, + const CMvDatabaseEx *database, const CRecordVector<bool> *extractStatuses, int startIndex, - int numFiles, + UInt64 folderSize, IArchiveExtractCallback *extractCallback, - UInt64 startImportantTotalUnPacked, bool testMode) { - m_Folders = folders; - m_Files = files; - m_FileIndexes = fileIndices; + m_Database = database; m_ExtractStatuses = extractStatuses; m_StartIndex = startIndex; - m_NumFiles = numFiles; + m_FolderSize = folderSize; + m_ExtractCallback = extractCallback; - m_StartImportantTotalUnPacked = startImportantTotalUnPacked; m_TestMode = testMode; m_CurrentIndex = 0; + m_PosInFolder = 0; m_FileIsOpen = false; + m_IsOk = true; } -HRESULT CCabFolderOutStream::OpenFile(int indexIndex, ISequentialOutStream **realOutStream) +HRESULT CCabFolderOutStream::OpenFile() { - // RINOK(m_ExtractCallback->SetCompleted(&m_StartImportantTotalUnPacked)); - - int fullIndex = m_StartIndex + indexIndex; - - Int32 askMode; - if((*m_ExtractStatuses)[fullIndex]) - askMode = m_TestMode ? - NArchive::NExtract::NAskMode::kTest : - NArchive::NExtract::NAskMode::kExtract; - else + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); + if (!m_RealOutStream && !m_TestMode) askMode = NArchive::NExtract::NAskMode::kSkip; - - int index = (*m_FileIndexes)[fullIndex]; - const CItem &fileInfo = (*m_Files)[index]; - UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( - m_Folders->Size(), fileInfo.FolderIndex); - - RINOK(m_ExtractCallback->GetStream(index, realOutStream, askMode)); - - UInt64 currentUnPackSize = fileInfo.UnPackSize; - - bool mustBeProcessedAnywhere = (indexIndex < m_NumFiles - 1); - - if (realOutStream || mustBeProcessedAnywhere) - { - if (!realOutStream && !m_TestMode) - askMode = NArchive::NExtract::NAskMode::kSkip; - RINOK(m_ExtractCallback->PrepareOperation(askMode)); - return S_OK; - } - else - return S_FALSE; + return m_ExtractCallback->PrepareOperation(askMode); } - HRESULT CCabFolderOutStream::WriteEmptyFiles() { - for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) + if (m_FileIsOpen) + return S_OK; + for(;m_CurrentIndex < m_ExtractStatuses->Size(); m_CurrentIndex++) { - int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex]; - const CItem &fileInfo = (*m_Files)[index]; - if (fileInfo.UnPackSize != 0) + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + UInt64 fileSize = item.Size; + if (fileSize != 0) return S_OK; - realOutStream.Release(); - HRESULT result = OpenFile(m_CurrentIndex, &realOutStream); - realOutStream.Release(); - if (result == S_FALSE) - { - } - else if (result == S_OK) - { - RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); - } - else - return result; + HRESULT result = OpenFile(); + m_RealOutStream.Release(); + RINOK(result); + RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); } return S_OK; } -STDMETHODIMP CCabFolderOutStream::Write(const void *data, - UInt32 size, UInt32 *processedSize) +// This is Write function +HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) { - UInt32 processedSizeReal = 0; - while(m_CurrentIndex < m_NumFiles) + UInt32 realProcessed = 0; + if (processedSize != NULL) + *processedSize = 0; + while(size != 0) { if (m_FileIsOpen) { - int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex]; - const CItem &fileInfo = (*m_Files)[index]; - UInt64 fileSize = fileInfo.UnPackSize; - - UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - m_FilePos, - UInt64(size - processedSizeReal)); - - UInt32 processedSizeLocal; - if (!realOutStream) - { - processedSizeLocal = numBytesToWrite; - } - else + UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); + HRESULT res = S_OK; + if (numBytesToWrite > 0) { - RINOK(realOutStream->Write((const Byte *)data + processedSizeReal, numBytesToWrite, &processedSizeLocal)); + if (!isOK) + m_IsOk = false; + if (m_RealOutStream) + { + UInt32 processedSizeLocal = 0; + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + numBytesToWrite = processedSizeLocal; + } } - m_FilePos += processedSizeLocal; - processedSizeReal += processedSizeLocal; - if (m_FilePos == fileInfo.UnPackSize) + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_RemainFileSize -= numBytesToWrite; + m_PosInFolder += numBytesToWrite; + if (res != S_OK) + return res; + if (m_RemainFileSize == 0) { - realOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult( + m_IsOk ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); m_FileIsOpen = false; - m_CurrentIndex++; - } - if (processedSizeReal == size) - { - RINOK(WriteEmptyFiles()); - if (processedSize != NULL) - *processedSize = processedSizeReal; - return S_OK; } + if (realProcessed > 0) + break; // with this break this function works as Write-Part } else { - HRESULT result = OpenFile(m_CurrentIndex, &realOutStream); - if (result != S_FALSE && result != S_OK) - return result; - m_FileIsOpen = true; - m_FilePos = 0; + if (m_CurrentIndex >= m_ExtractStatuses->Size()) + return E_FAIL; + + const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex]; + const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + + m_RemainFileSize = item.Size; + + UInt32 fileOffset = item.Offset; + if (fileOffset < m_PosInFolder) + return E_FAIL; + if (fileOffset > m_PosInFolder) + { + UInt32 numBytesToWrite = (UInt32)MyMin((UInt64)fileOffset - m_PosInFolder, UInt64(size)); + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_PosInFolder += numBytesToWrite; + } + if (fileOffset == m_PosInFolder) + { + RINOK(OpenFile()); + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + } } } - if (processedSize != NULL) - *processedSize = size; - return S_OK; + return WriteEmptyFiles(); +} + +STDMETHODIMP CCabFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write2(data, size, processedSize, true); } HRESULT CCabFolderOutStream::FlushCorrupted() { - // UInt32 processedSizeReal = 0; - while(m_CurrentIndex < m_NumFiles) + const UInt32 kBufferSize = (1 << 10); + Byte buffer[kBufferSize]; + for (int i = 0; i < kBufferSize; i++) + buffer[i] = 0; + while(true) { - if (m_FileIsOpen) - { - int index = (*m_FileIndexes)[m_StartIndex + m_CurrentIndex]; - const CItem &fileInfo = (*m_Files)[index]; - UInt64 fileSize = fileInfo.UnPackSize; - - realOutStream.Release(); - RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kCRCError)); - m_FileIsOpen = false; - m_CurrentIndex++; - } - else - { - HRESULT result = OpenFile(m_CurrentIndex, &realOutStream); - if (result != S_FALSE && result != S_OK) - return result; - m_FileIsOpen = true; - } + UInt64 remain = GetRemain(); + if (remain == 0) + return S_OK; + UInt32 size = (UInt32)MyMin(remain, (UInt64)kBufferSize); + UInt32 processedSizeLocal = 0; + RINOK(Write2(buffer, size, &processedSizeLocal, false)); } - return S_OK; } HRESULT CCabFolderOutStream::Unsupported() { - while(m_CurrentIndex < m_NumFiles) + while(m_CurrentIndex < m_ExtractStatuses->Size()) { - HRESULT result = OpenFile(m_CurrentIndex, &realOutStream); + HRESULT result = OpenFile(); if (result != S_FALSE && result != S_OK) return result; - realOutStream.Release(); + m_RealOutStream.Release(); RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); m_CurrentIndex++; } return S_OK; } -STDMETHODIMP CCabFolderOutStream::WritePart(const void *data, - UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, Int32 _aTestMode, IArchiveExtractCallback *extractCallback) { COM_TRY_BEGIN - bool allFilesMode = (numItems == UInt32(-1)); + bool allFilesMode = (numItems == (UInt32)(-1)); if (allFilesMode) - numItems = m_Files.Size(); + numItems = m_Database.Items.Size(); if(numItems == 0) return S_OK; bool testMode = (_aTestMode != 0); - UInt64 censoredTotalUnPacked = 0, importantTotalUnPacked = 0; + UInt64 totalUnPacked = 0; int lastIndex = 0; - CRecordVector<int> folderIndexes; - CRecordVector<int> importantIndices; - CRecordVector<bool> extractStatuses; UInt32 i; + int lastFolder = -2; + UInt64 lastFolderSize = 0; for(i = 0; i < numItems; i++) { int index = allFilesMode ? i : indices[i]; - const CItem &fileInfo = m_Files[index]; - censoredTotalUnPacked += fileInfo.UnPackSize; - - int folderIndex = fileInfo.FolderIndex; - if (folderIndexes.IsEmpty()) - folderIndexes.Add(folderIndex); - else - { - if (folderIndex != folderIndexes.Back()) - folderIndexes.Add(folderIndex); - } - - int j; - for(j = index - 1; j >= lastIndex; j--) - if(m_Files[j].FolderIndex != folderIndex) - break; - for(j++; j <= index; j++) - { - const CItem &fileInfo = m_Files[j]; - importantTotalUnPacked += fileInfo.UnPackSize; - importantIndices.Add(j); - extractStatuses.Add(j == index); - } - lastIndex = index + 1; + const CMvItem &mvItem = m_Database.Items[index]; + const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDirectory()) + continue; + int folderIndex = m_Database.GetFolderIndex(&mvItem); + if (folderIndex != lastFolder) + totalUnPacked += lastFolderSize; + lastFolder = folderIndex; + lastFolderSize = item.GetEndOffset(); } + totalUnPacked += lastFolderSize; + + extractCallback->SetTotal(totalUnPacked); - extractCallback->SetTotal(importantTotalUnPacked); - UInt64 currentImportantTotalUnPacked = 0; - UInt64 currentImportantTotalPacked = 0; + totalUnPacked = 0; - CCopyDecoder *storeDecoderSpec = NULL; - CMyComPtr<ICompressCoder> storeDecoder; + NCompress::CCopyCoder *copyCoderSpec = NULL; + CMyComPtr<ICompressCoder> copyCoder; - NMSZip::CDecoder *msZipDecoderSpec = NULL; - CMyComPtr<ICompressCoder> msZipDecoder; + NCompress::NDeflate::NDecoder::CCOMCoder *deflateDecoderSpec = NULL; + CMyComPtr<ICompressCoder> deflateDecoder; - NLZX::CDecoder *lzxDecoderSpec = NULL; + NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL; CMyComPtr<ICompressCoder> lzxDecoder; + NCompress::NQuantum::CDecoder *quantumDecoderSpec = NULL; + CMyComPtr<ICompressCoder> quantumDecoder; - int curImportantIndexIndex = 0; - UInt64 totalFolderUnPacked; - for(i = 0; i < (UInt32)folderIndexes.Size(); i++, currentImportantTotalUnPacked += totalFolderUnPacked) + CCabBlockInStream *cabBlockInStreamSpec = new CCabBlockInStream(); + CMyComPtr<ISequentialInStream> cabBlockInStream = cabBlockInStreamSpec; + if (!cabBlockInStreamSpec->Create()) + return E_OUTOFMEMORY; + + CRecordVector<bool> extractStatuses; + for(i = 0; i < numItems;) { - int folderIndex = folderIndexes[i]; - UInt16 realFolderIndex = NHeader::NFolderIndex::GetRealFolderIndex( - m_Folders.Size(), folderIndex); - - RINOK(extractCallback->SetCompleted(¤tImportantTotalUnPacked)); - totalFolderUnPacked = 0; - int j; - for (j = curImportantIndexIndex; j < importantIndices.Size(); j++) + int index = allFilesMode ? i : indices[i]; + + const CMvItem &mvItem = m_Database.Items[index]; + const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex]; + int itemIndex = mvItem.ItemIndex; + const CItem &item = db.Items[itemIndex]; + + i++; + if (item.IsDirectory()) { - const CItem &fileInfo = m_Files[importantIndices[j]]; - if (fileInfo.FolderIndex != folderIndex) + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + int folderIndex = m_Database.GetFolderIndex(&mvItem); + if (folderIndex < 0) + { + // If we need previous archive + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kDataError)); + continue; + } + int startIndex2 = m_Database.FolderStartFileIndex[folderIndex]; + int startIndex = startIndex2; + extractStatuses.Clear(); + for (; startIndex < index; startIndex++) + extractStatuses.Add(false); + extractStatuses.Add(true); + startIndex++; + UInt64 curUnpack = item.GetEndOffset(); + for(;i < numItems; i++) + { + int indexNext = allFilesMode ? i : indices[i]; + const CMvItem &mvItem = m_Database.Items[indexNext]; + const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDirectory()) + continue; + int newFolderIndex = m_Database.GetFolderIndex(&mvItem); + + if (newFolderIndex != folderIndex) break; - totalFolderUnPacked += fileInfo.UnPackSize; + for (; startIndex < indexNext; startIndex++) + extractStatuses.Add(false); + extractStatuses.Add(true); + startIndex++; + curUnpack = item.GetEndOffset(); } + + RINOK(extractCallback->SetCompleted(&totalUnPacked)); - CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream; + CCabFolderOutStream *cabFolderOutStream = new CCabFolderOutStream; CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream); - const NHeader::CFolder &folder = m_Folders[realFolderIndex]; + const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())]; - cabFolderOutStream->Init(&m_Folders, &m_Files, &importantIndices, - &extractStatuses, curImportantIndexIndex, j - curImportantIndexIndex, - extractCallback, currentImportantTotalUnPacked, - folder.GetCompressionMethod() == NHeader::NCompressionMethodMajor::kQuantum? - true: testMode); - - curImportantIndexIndex = j; - - UInt64 pos = folder.DataStart; // test it (+ archiveStart) - RINOK(m_Stream->Seek(pos, STREAM_SEEK_SET, NULL)); - - CLocalProgress *localProgressSpec = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; - localProgressSpec->Init(extractCallback, false); - - CLocalCompressProgressInfo *localCompressProgressSpec = - new CLocalCompressProgressInfo; - CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; - localCompressProgressSpec->Init(progress, - NULL, ¤tImportantTotalUnPacked); - - Byte reservedSize = m_ArchiveInfo.ReserveBlockPresent() ? - m_ArchiveInfo.PerDataSizes.PerDatablockAreaSize : 0; + cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, + curUnpack, extractCallback, testMode); + cabBlockInStreamSpec->MsZip = false; switch(folder.GetCompressionMethod()) { case NHeader::NCompressionMethodMajor::kNone: - { - if(storeDecoderSpec == NULL) + if(copyCoderSpec == NULL) { - storeDecoderSpec = new CCopyDecoder; - storeDecoder = storeDecoderSpec; - } - try - { - storeDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks); - RINOK(storeDecoder->Code(m_Stream, outStream, - NULL, &totalFolderUnPacked, compressProgress)); - } - catch(...) - { - RINOK(cabFolderOutStream->FlushCorrupted()); - continue; + copyCoderSpec = new NCompress::CCopyCoder; + copyCoder = copyCoderSpec; } break; - } case NHeader::NCompressionMethodMajor::kMSZip: - { - if(lzxDecoderSpec == NULL) + if(deflateDecoderSpec == NULL) { - msZipDecoderSpec = new NMSZip::CDecoder; - msZipDecoder = msZipDecoderSpec; + deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder; + deflateDecoder = deflateDecoderSpec; } - try + cabBlockInStreamSpec->MsZip = true; + break; + case NHeader::NCompressionMethodMajor::kLZX: + if(lzxDecoderSpec == NULL) { - msZipDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks); - RINOK(msZipDecoder->Code(m_Stream, outStream, - NULL, &totalFolderUnPacked, compressProgress)); + lzxDecoderSpec = new NCompress::NLzx::CDecoder; + lzxDecoder = lzxDecoderSpec; } - catch(...) + RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor)); + break; + case NHeader::NCompressionMethodMajor::kQuantum: + if(quantumDecoderSpec == NULL) { - RINOK(cabFolderOutStream->FlushCorrupted()); - continue; + quantumDecoderSpec = new NCompress::NQuantum::CDecoder; + quantumDecoder = quantumDecoderSpec; } + quantumDecoderSpec->SetParams(folder.CompressionTypeMinor); break; + default: + { + RINOK(cabFolderOutStream->Unsupported()); + totalUnPacked += curUnpack; + continue; } - case NHeader::NCompressionMethodMajor::kLZX: + } + + cabBlockInStreamSpec->InitForNewFolder(); + + HRESULT res = S_OK; + + { + int volIndex = mvItem.VolumeIndex; + int locFolderIndex = item.GetFolderIndex(db.Folders.Size()); + bool keepHistory = false; + bool keepInputBuffer = false; + for (UInt32 f = 0; cabFolderOutStream->GetRemain() != 0;) { - if(lzxDecoderSpec == NULL) + if (volIndex >= m_Database.Volumes.Size()) { - lzxDecoderSpec = new NLZX::CDecoder; - lzxDecoder = lzxDecoderSpec; + res = S_FALSE; + break; } - try + + const CDatabaseEx &db = m_Database.Volumes[volIndex]; + const CFolder &folder = db.Folders[locFolderIndex]; + if (f == 0) { - lzxDecoderSpec->SetParams(reservedSize, folder.NumDataBlocks, - folder.CompressionTypeMinor); - RINOK(lzxDecoder->Code(m_Stream, outStream, - NULL, &totalFolderUnPacked, compressProgress)); + cabBlockInStreamSpec->SetStream(db.Stream); + cabBlockInStreamSpec->ReservedSize = db.ArchiveInfo.GetDataBlockReserveSize(); + RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL)); } - catch(...) + if (f == folder.NumDataBlocks) { - RINOK(cabFolderOutStream->FlushCorrupted()); + volIndex++; + locFolderIndex = 0; + f = 0; continue; } - break; + f++; + + cabBlockInStreamSpec->DataError = false; + + if (!keepInputBuffer) + cabBlockInStreamSpec->InitForNewBlock(); + + UInt32 packSize, unpackSize; + res = cabBlockInStreamSpec->PreRead(packSize, unpackSize); + if (res == S_FALSE) + break; + RINOK(res); + keepInputBuffer = (unpackSize == 0); + if (keepInputBuffer) + continue; + + + UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFolder(); + RINOK(extractCallback->SetCompleted(&totalUnPacked2)); + UInt64 unpackRemain = cabFolderOutStream->GetRemain(); + + const UInt32 kBlockSizeMax = (1 << 15); + if (unpackRemain > kBlockSizeMax) + unpackRemain = kBlockSizeMax; + if (unpackRemain > unpackSize) + unpackRemain = unpackSize; + + switch(folder.GetCompressionMethod()) + { + case NHeader::NCompressionMethodMajor::kNone: + res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + case NHeader::NCompressionMethodMajor::kMSZip: + deflateDecoderSpec->SetKeepHistory(keepHistory); + res = deflateDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + case NHeader::NCompressionMethodMajor::kLZX: + lzxDecoderSpec->SetKeepHistory(keepHistory, cabBlockInStreamSpec->GetAlign()); + res = lzxDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + case NHeader::NCompressionMethodMajor::kQuantum: + quantumDecoderSpec->SetKeepHistory(keepHistory); + res = quantumDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL); + break; + } + if (res != S_OK) + { + if (res != S_FALSE) + RINOK(res); + break; + } + keepHistory = true; + } + if (res == S_OK) + { + RINOK(cabFolderOutStream->WriteEmptyFiles()); } - default: - RINOK(cabFolderOutStream->Unsupported()); - // return E_FAIL; } + if (res != S_OK || cabFolderOutStream->GetRemain() != 0) + { + RINOK(cabFolderOutStream->FlushCorrupted()); + } + totalUnPacked += curUnpack; } return S_OK; COM_TRY_END @@ -631,9 +807,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) { COM_TRY_BEGIN - *numItems = m_Files.Size(); + *numItems = m_Database.Items.Size(); return S_OK; COM_TRY_END } -}}
\ No newline at end of file +}} diff --git a/7zip/Archive/Cab/CabHandler.h b/7zip/Archive/Cab/CabHandler.h index 584dadf8..2c14d468 100755 --- a/7zip/Archive/Cab/CabHandler.h +++ b/7zip/Archive/Cab/CabHandler.h @@ -37,10 +37,7 @@ public: BSTR *name, PROPID *propID, VARTYPE *varType); private: - CObjectVector<NHeader::CFolder> m_Folders; - CObjectVector<CItem> m_Files; - CInArchiveInfo m_ArchiveInfo; - CMyComPtr<IInStream> m_Stream; + CMvDatabaseEx m_Database; }; }} diff --git a/7zip/Archive/Cab/CabHeader.h b/7zip/Archive/Cab/CabHeader.h index 2eac96bf..5c122743 100755 --- a/7zip/Archive/Cab/CabHeader.h +++ b/7zip/Archive/Cab/CabHeader.h @@ -9,53 +9,15 @@ namespace NArchive { namespace NCab { namespace NHeader{ -namespace NArchive { - +namespace NArchive +{ extern UInt32 kSignature; - namespace NFlags { const int kPrevCabinet = 0x0001; const int kNextCabinet = 0x0002; const int kReservePresent = 0x0004; } - - const UInt32 kArchiveHeaderSize = 36; - /* - struct CBlock - { - UInt32 Signature; // cabinet file signature - UInt32 Reserved1; // reserved - UInt32 Size; // size of this cabinet file in bytes - UInt32 Reserved2; // reserved - UInt32 FileOffset; // offset of the first CFFILE entry - UInt32 Reserved3; // reserved - Byte VersionMinor; // cabinet file format version, minor - Byte VersionMajor; // cabinet file format version, major - UInt16 NumFolders; // number of CFFOLDER entries in this cabinet - UInt16 NumFiles; // number of CFFILE entries in this cabinet - UInt16 Flags; // cabinet file option indicators - UInt16 SetID; // must be the same for all cabinets in a set - UInt16 CabinetNumber; // number of this cabinet file in a set - }; - */ - - const UInt32 kPerDataSizesHeaderSize = 4; - - struct CPerDataSizes - { - UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area - Byte PerFolderAreaSize; // (optional) size of per-folder reserved area - Byte PerDatablockAreaSize; // (optional) size of per-datablock reserved area - }; - - /* - Byte abReserve[]; // (optional) per-cabinet reserved area - Byte szCabinetPrev[]; // (optional) name of previous cabinet file - Byte szDiskPrev[]; // (optional) name of previous disk - Byte szCabinetNext[]; // (optional) name of next cabinet file - Byte szDiskNext[]; // (optional) name of next disk - */ } namespace NCompressionMethodMajor @@ -66,17 +28,6 @@ namespace NCompressionMethodMajor const Byte kLZX = 3; } -const UInt32 kFolderHeaderSize = 8; -struct CFolder -{ - UInt32 DataStart; // offset of the first CFDATA block in this folder - UInt16 NumDataBlocks; // number of CFDATA blocks in this folder - Byte CompressionTypeMajor; - Byte CompressionTypeMinor; - // Byte abReserve[]; // (optional) per-folder reserved area - Byte GetCompressionMethod() const { return CompressionTypeMajor & 0xF; } -}; - const int kFileNameIsUTFAttributeMask = 0x80; namespace NFolderIndex @@ -84,34 +35,8 @@ namespace NFolderIndex const int kContinuedFromPrev = 0xFFFD; const int kContinuedToNext = 0xFFFE; const int kContinuedPrevAndNext = 0xFFFF; - inline UInt16 GetRealFolderIndex(UInt16 aNumFolders, UInt16 aFolderIndex) - { - switch(aFolderIndex) - { - case kContinuedFromPrev: - return 0; - case kContinuedToNext: - case kContinuedPrevAndNext: - return aNumFolders - 1; - default: - return aFolderIndex; - } - } } -const UInt32 kFileHeaderSize = 16; -/* -struct CFile -{ - UInt32 UnPackSize; // uncompressed size of this file in bytes - UInt32 UnPackOffset; // uncompressed offset of this file in the folder - UInt16 FolderIndex; // index into the CFFOLDER area - UInt16 PureDate; - UInt16 PureTime; // Time - UInt16 Attributes; // attribute flags for this file - Byte szName[]; // name of this file -}; -*/ }}} #endif diff --git a/7zip/Archive/Cab/CabIn.cpp b/7zip/Archive/Cab/CabIn.cpp index a9d40726..1d47502c 100755 --- a/7zip/Archive/Cab/CabIn.cpp +++ b/7zip/Archive/Cab/CabIn.cpp @@ -6,7 +6,8 @@ #include "Common/MyCom.h" #include "CabIn.h" #include "Windows/Defs.h" -#include "../../Common/InBuffer.h" + +#include "../../Common/StreamUtils.h" namespace NArchive{ namespace NCab{ @@ -14,7 +15,7 @@ namespace NCab{ static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) { UInt32 realProcessedSize; - RINOK(inStream->Read(data, size, &realProcessedSize)); + RINOK(ReadStream(inStream, data, size, &realProcessedSize)); if(realProcessedSize != size) return S_FALSE; return S_OK; @@ -23,7 +24,7 @@ static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size) static HRESULT SafeRead(IInStream *inStream, void *data, UInt32 size) { UInt32 realProcessedSize; - RINOK(inStream->Read(data, size, &realProcessedSize)); + RINOK(ReadStream(inStream, data, size, &realProcessedSize)); if(realProcessedSize != size) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); return S_OK; @@ -37,25 +38,12 @@ static void SafeInByteRead(::CInBuffer &inBuffer, void *data, UInt32 size) throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); } -static void SafeReadName(::CInBuffer &inBuffer, AString &name) -{ - name.Empty(); - while(true) - { - Byte b; - if (!inBuffer.ReadByte(b)) - throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); - if (b == 0) - return; - name += char(b); - } -} - Byte CInArchive::ReadByte() { - if (_blockPos >= _blockSize) - throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive); - return _block[_blockPos++]; + Byte b; + if (!inBuffer.ReadByte(b)) + throw CInArchiveException(CInArchiveException::kUnsupported); + return b; } UInt16 CInArchive::ReadUInt16() @@ -80,20 +68,38 @@ UInt32 CInArchive::ReadUInt32() return value; } -HRESULT CInArchive::Open(IInStream *inStream, - const UInt64 *searchHeaderSizeLimit, - CInArchiveInfo &inArchiveInfo, - CObjectVector<NHeader::CFolder> &folders, - CObjectVector<CItem> &files, - CProgressVirt *progressVirt) +AString CInArchive::SafeReadName() { - UInt64 startPosition; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &startPosition)); + AString name; + while(true) + { + Byte b = ReadByte(); + if (b == 0) + return name; + name += (char)b; + } +} - // NHeader::NArchive::CBlock archiveHeader; +void CInArchive::ReadOtherArchive(COtherArchive &oa) +{ + oa.FileName = SafeReadName(); + oa.DiskName = SafeReadName(); +} + +void CInArchive::Skeep(size_t size) +{ + while (size-- != 0) + ReadByte(); +} + +HRESULT CInArchive::Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CDatabase &database) +{ + database.Clear(); + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition)); { - ::CInBuffer inBuffer; if (!inBuffer.Create(1 << 17)) return E_OUTOFMEMORY; inBuffer.SetStream(inStream); @@ -117,141 +123,219 @@ HRESULT CInArchive::Open(IInStream *inStream, return S_FALSE; } } - startPosition += inBuffer.GetProcessedSize() - kSignatureSize; + database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize; } - RINOK(inStream->Seek(startPosition, STREAM_SEEK_SET, NULL)); - - RINOK(ReadBytes(inStream, _block, NHeader::NArchive::kArchiveHeaderSize)); - _blockSize = NHeader::NArchive::kArchiveHeaderSize; - _blockPos = 0; - - ReadUInt32(); // Signature; // cabinet file signature - // if (archiveHeader.Signature != NHeader::NArchive::kSignature) - // return S_FALSE; - - UInt32 reserved1 = ReadUInt32(); - UInt32 size = ReadUInt32(); // size of this cabinet file in bytes - UInt32 reserved2 = ReadUInt32(); - UInt32 fileOffset = ReadUInt32(); // offset of the first CFFILE entry - UInt32 reserved3 = ReadUInt32(); - - inArchiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor - inArchiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major - inArchiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet - inArchiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet - inArchiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet - UInt16 setID = ReadUInt16(); // must be the same for all cabinets in a set - UInt16 cabinetNumber = ReadUInt16(); // number of this cabinet file in a set - - if (reserved1 != 0 || reserved2 != 0 || reserved3 != 0) - throw CInArchiveException(CInArchiveException::kUnsupported); - if (inArchiveInfo.ReserveBlockPresent()) + CInArchiveInfo &archiveInfo = database.ArchiveInfo; + + archiveInfo.Size = ReadUInt32(); // size of this cabinet file in bytes + if (ReadUInt32() != 0) + return S_FALSE; + archiveInfo.FileHeadersOffset = ReadUInt32(); // offset of the first CFFILE entry + if (ReadUInt32() != 0) + return S_FALSE; + + archiveInfo.VersionMinor = ReadByte(); // cabinet file format version, minor + archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major + archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet + archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet + archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet + archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set + archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set + + if (archiveInfo.ReserveBlockPresent()) { - RINOK(SafeRead(inStream, _block, NHeader::NArchive::kPerDataSizesHeaderSize)); - _blockSize = NHeader::NArchive::kPerDataSizesHeaderSize; - _blockPos = 0; - - inArchiveInfo.PerDataSizes.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area - inArchiveInfo.PerDataSizes.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area - inArchiveInfo.PerDataSizes.PerDatablockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area - RINOK(inStream->Seek(inArchiveInfo.PerDataSizes.PerCabinetAreaSize, - STREAM_SEEK_CUR, NULL)); + archiveInfo.PerCabinetAreaSize = ReadUInt16(); // (optional) size of per-cabinet reserved area + archiveInfo.PerFolderAreaSize = ReadByte(); // (optional) size of per-folder reserved area + archiveInfo.PerDataBlockAreaSize = ReadByte(); // (optional) size of per-datablock reserved area + + Skeep(archiveInfo.PerCabinetAreaSize); } { - UInt64 foldersStartPosition; - RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &foldersStartPosition)); - ::CInBuffer inBuffer; - if (!inBuffer.Create(1 << 17)) - return E_OUTOFMEMORY; - inBuffer.SetStream(inStream); - inBuffer.Init(); - if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0) - { - SafeReadName(inBuffer, inArchiveInfo.PreviousCabinetName); - SafeReadName(inBuffer, inArchiveInfo.PreviousDiskName); - } - if ((inArchiveInfo.Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0) - { - SafeReadName(inBuffer, inArchiveInfo.NextCabinetName); - SafeReadName(inBuffer, inArchiveInfo.NextDiskName); - } - foldersStartPosition += inBuffer.GetProcessedSize(); - RINOK(inStream->Seek(foldersStartPosition, STREAM_SEEK_SET, NULL)); + if (archiveInfo.IsTherePrev()) + ReadOtherArchive(archiveInfo.PreviousArchive); + if (archiveInfo.IsThereNext()) + ReadOtherArchive(archiveInfo.NextArchive); } - if (progressVirt != NULL) - { - UInt64 numFiles = inArchiveInfo.NumFiles; - RINOK(progressVirt->SetTotal(&numFiles)); - } - folders.Clear(); int i; - for(i = 0; i < inArchiveInfo.NumFolders; i++) + for(i = 0; i < archiveInfo.NumFolders; i++) { - if (progressVirt != NULL) - { - UInt64 numFiles = 0; - RINOK(progressVirt->SetCompleted(&numFiles)); - } - NHeader::CFolder folder; - RINOK(SafeRead(inStream, _block, NHeader::kFolderHeaderSize)); - _blockSize = NHeader::kFolderHeaderSize; - _blockPos = 0; + CFolder folder; folder.DataStart = ReadUInt32(); folder.NumDataBlocks = ReadUInt16(); folder.CompressionTypeMajor = ReadByte(); folder.CompressionTypeMinor = ReadByte(); - if (inArchiveInfo.ReserveBlockPresent()) - { - RINOK(inStream->Seek( - inArchiveInfo.PerDataSizes.PerFolderAreaSize, STREAM_SEEK_CUR, NULL)); - } - folder.DataStart += (UInt32)startPosition; - folders.Add(folder); + Skeep(archiveInfo.PerFolderAreaSize); + database.Folders.Add(folder); } - RINOK(inStream->Seek(startPosition + fileOffset, - STREAM_SEEK_SET, NULL)); + RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL)); - ::CInBuffer inBuffer; - if (!inBuffer.Create(1 << 17)) - return E_OUTOFMEMORY; inBuffer.SetStream(inStream); inBuffer.Init(); - files.Clear(); - if (progressVirt != NULL) - { - UInt64 numFiles = files.Size(); - RINOK(progressVirt->SetCompleted(&numFiles)); - } - for(i = 0; i < inArchiveInfo.NumFiles; i++) + for(i = 0; i < archiveInfo.NumFiles; i++) { - SafeInByteRead(inBuffer, _block, NHeader::kFileHeaderSize); - _blockSize = NHeader::kFileHeaderSize; - _blockPos = 0; CItem item; - item.UnPackSize = ReadUInt32(); - item.UnPackOffset = ReadUInt32(); + item.Size = ReadUInt32(); + item.Offset = ReadUInt32(); item.FolderIndex = ReadUInt16(); - if (item.FolderIndex > inArchiveInfo.NumFolders) - return S_FALSE; UInt16 pureDate = ReadUInt16(); UInt16 pureTime = ReadUInt16(); item.Time = ((UInt32(pureDate) << 16)) | pureTime; item.Attributes = ReadUInt16(); - SafeReadName(inBuffer, item.Name); - files.Add(item); - if (progressVirt != NULL) + item.Name = SafeReadName(); + int folderIndex = item.GetFolderIndex(database.Folders.Size()); + if (folderIndex >= database.Folders.Size()) + return S_FALSE; + database.Items.Add(item); + } + return S_OK; +} + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +HRESULT CInArchive::Open( + const UInt64 *searchHeaderSizeLimit, + CDatabaseEx &database) +{ + return Open2(database.Stream, searchHeaderSizeLimit, database); +} + + +static int CompareMvItems2(const CMvItem *p1, const CMvItem *p2) +{ + RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex)); + return MyCompare(p1->ItemIndex, p2->ItemIndex); +} + +static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param) +{ + const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param; + const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex]; + const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex]; + const CItem &item1 = db1.Items[p1->ItemIndex]; + const CItem &item2 = db2.Items[p2->ItemIndex];; + bool isDir1 = item1.IsDirectory(); + bool isDir2 = item2.IsDirectory(); + if (isDir1 && !isDir2) + return -1; + if (isDir2 && !isDir1) + return 1; + int f1 = mvDb.GetFolderIndex(p1); + int f2 = mvDb.GetFolderIndex(p2); + RINOZ(MyCompare(f1, f2)); + RINOZ(MyCompare(item1.Offset, item2.Offset)); + RINOZ(MyCompare(item1.Size, item2.Size)); + return CompareMvItems2(p1, p2); +} + +bool CMvDatabaseEx::AreItemsEqual(int i1, int i2) +{ + const CMvItem *p1 = &Items[i1]; + const CMvItem *p2 = &Items[i2]; + const CDatabaseEx &db1 = Volumes[p1->VolumeIndex]; + const CDatabaseEx &db2 = Volumes[p2->VolumeIndex]; + const CItem &item1 = db1.Items[p1->ItemIndex]; + const CItem &item2 = db2.Items[p2->ItemIndex];; + int f1 = GetFolderIndex(p1); + int f2 = GetFolderIndex(p2); + if (f1 != f2) + return false; + if (item1.Offset != item2.Offset) + return false; + if (item1.Size != item2.Size) + return false; + + return true; +} + +void CMvDatabaseEx::FillSortAndShrink() +{ + Items.Clear(); + StartFolderOfVol.Clear(); + FolderStartFileIndex.Clear(); + int offset = 0; + for (int v = 0; v < Volumes.Size(); v++) + { + const CDatabaseEx &db = Volumes[v]; + int curOffset = offset; + if (db.IsTherePrevFolder()) + curOffset--; + StartFolderOfVol.Add(curOffset); + offset += db.GetNumberOfNewFolders(); + + CMvItem mvItem; + mvItem.VolumeIndex = v; + for (int i = 0 ; i < db.Items.Size(); i++) { - UInt64 numFiles = files.Size(); - RINOK(progressVirt->SetCompleted(&numFiles)); + mvItem.ItemIndex = i; + Items.Add(mvItem); } } - return S_OK; + + Items.Sort(CompareMvItems, (void *)this); + int j = 1; + int i; + for (i = 1; i < Items.Size(); i++) + if (!AreItemsEqual(i, i -1)) + Items[j++] = Items[i]; + Items.DeleteFrom(j); + + for (i = 0; i < Items.Size(); i++) + { + const CMvItem &mvItem = Items[i]; + int folderIndex = GetFolderIndex(&mvItem); + if (folderIndex >= FolderStartFileIndex.Size()) + FolderStartFileIndex.Add(i); + } +} + +bool CMvDatabaseEx::Check() +{ + for (int v = 1; v < Volumes.Size(); v++) + { + const CDatabaseEx &db1 = Volumes[v]; + if (db1.IsTherePrevFolder()) + { + const CDatabaseEx &db0 = Volumes[v - 1]; + if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty()) + return false; + const CFolder &f0 = db0.Folders.Back(); + const CFolder &f1 = db1.Folders.Front(); + if (f0.CompressionTypeMajor != f1.CompressionTypeMajor || + f0.CompressionTypeMinor != f1.CompressionTypeMinor) + return false; + } + } + UInt64 maxPos = 0; + int prevFolder = -2; + for(int i = 0; i < Items.Size(); i++) + { + const CMvItem &mvItem = Items[i]; + int fIndex = GetFolderIndex(&mvItem); + if (fIndex >= FolderStartFileIndex.Size()) + return false; + const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; + if (item.IsDirectory()) + continue; + int folderIndex = GetFolderIndex(&mvItem); + if (folderIndex != prevFolder) + { + prevFolder = folderIndex; + maxPos = 0; + continue; + } + if (item.Offset < maxPos) + return false; + maxPos = item.GetEndOffset(); + if (maxPos < item.Offset) + return false; + } + return true; } }} diff --git a/7zip/Archive/Cab/CabIn.h b/7zip/Archive/Cab/CabIn.h index 82a9ea0d..4e817e94 100755 --- a/7zip/Archive/Cab/CabIn.h +++ b/7zip/Archive/Cab/CabIn.h @@ -4,6 +4,7 @@ #define __ARCHIVE_CAB_IN_H #include "../../IStream.h" +#include "../../Common/InBuffer.h" #include "CabHeader.h" #include "CabItem.h" @@ -22,10 +23,14 @@ public: CInArchiveException(CCauseType cause) : Cause(cause) {} }; -class CInArchiveInfo +struct COtherArchive +{ + AString FileName; + AString DiskName; +}; + +struct CArchiveInfo { -public: - UInt32 Size; /* size of this cabinet file in bytes */ Byte VersionMinor; /* cabinet file format version, minor */ Byte VersionMajor; /* cabinet file format version, major */ UInt16 NumFolders; /* number of CFFOLDER entries in this cabinet */ @@ -35,39 +40,125 @@ public: UInt16 CabinetNumber; /* number of this cabinet file in a set */ bool ReserveBlockPresent() const { return (Flags & NHeader::NArchive::NFlags::kReservePresent) != 0; } - NHeader::NArchive::CPerDataSizes PerDataSizes; - AString PreviousCabinetName; - AString PreviousDiskName; - AString NextCabinetName; - AString NextDiskName; + bool IsTherePrev() const { return (Flags & NHeader::NArchive::NFlags::kPrevCabinet) != 0; } + bool IsThereNext() const { return (Flags & NHeader::NArchive::NFlags::kNextCabinet) != 0; } + + UInt16 PerCabinetAreaSize; // (optional) size of per-cabinet reserved area + Byte PerFolderAreaSize; // (optional) size of per-folder reserved area + Byte PerDataBlockAreaSize; // (optional) size of per-datablock reserved area + + Byte GetDataBlockReserveSize() const { return (Byte)(ReserveBlockPresent() ? PerDataBlockAreaSize : 0); } + + COtherArchive PreviousArchive; + COtherArchive NextArchive; + + CArchiveInfo() + { + Clear(); + } + + void Clear() + { + PerCabinetAreaSize = 0; + PerFolderAreaSize = 0; + PerDataBlockAreaSize = 0; + } +}; + +struct CInArchiveInfo: public CArchiveInfo +{ + UInt32 Size; /* size of this cabinet file in bytes */ + UInt32 FileHeadersOffset; //offset of the first CFFILE entry +}; + + +class CDatabase +{ +public: + UInt64 StartPosition; + CInArchiveInfo ArchiveInfo; + CObjectVector<CFolder> Folders; + CObjectVector<CItem> Items; + void Clear() + { + ArchiveInfo.Clear(); + Folders.Clear(); + Items.Clear(); + } + bool IsTherePrevFolder() const + { + for (int i = 0; i < Items.Size(); i++) + if (Items[i].ContinuedFromPrev()) + return true; + return false; + } + int GetNumberOfNewFolders() const + { + int res = Folders.Size(); + if (IsTherePrevFolder()) + res--; + return res; + } + UInt32 GetFileOffset(int index) const { return Items[index].Offset; } + UInt32 GetFileSize(int index) const { return Items[index].Size; } }; -class CProgressVirt +class CDatabaseEx: public CDatabase { public: - STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE; - STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; + CMyComPtr<IInStream> Stream; +}; + +struct CMvItem +{ + int VolumeIndex; + int ItemIndex; }; -const UInt32 kMaxBlockSize = NHeader::NArchive::kArchiveHeaderSize; +class CMvDatabaseEx +{ + bool AreItemsEqual(int i1, int i2); +public: + CObjectVector<CDatabaseEx> Volumes; + CRecordVector<CMvItem> Items; + CRecordVector<int> StartFolderOfVol; + CRecordVector<int> FolderStartFileIndex; + int GetFolderIndex(const CMvItem *mvi) const + { + const CDatabaseEx &db = Volumes[mvi->VolumeIndex]; + return StartFolderOfVol[mvi->VolumeIndex] + + db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size()); + } + void Clear() + { + Volumes.Clear(); + Items.Clear(); + StartFolderOfVol.Clear(); + FolderStartFileIndex.Clear(); + } + void FillSortAndShrink(); + bool Check(); +}; class CInArchive { - UInt16 _blockSize; - Byte _block[kMaxBlockSize]; - UInt32 _blockPos; + CInBuffer inBuffer; Byte ReadByte(); UInt16 ReadUInt16(); UInt32 ReadUInt32(); + AString SafeReadName(); + void Skeep(size_t size); + void ReadOtherArchive(COtherArchive &oa); + + HRESULT Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CDatabase &database); public: - HRESULT Open(IInStream *inStream, + HRESULT Open( const UInt64 *searchHeaderSizeLimit, - CInArchiveInfo &inArchiveInfo, - CObjectVector<NHeader::CFolder> &folders, - CObjectVector<CItem> &files, - CProgressVirt *progressVirt); + CDatabaseEx &database); }; }} diff --git a/7zip/Archive/Cab/CabInBuffer.cpp b/7zip/Archive/Cab/CabInBuffer.cpp deleted file mode 100755 index c429033c..00000000 --- a/7zip/Archive/Cab/CabInBuffer.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// Archive/CabInBuffer.cpp - -#include "StdAfx.h" - -#include "../../../Common/Alloc.h" -#include "../../../Common/MyCom.h" -#include "../../../Windows/Defs.h" -#include "CabInBuffer.h" - -namespace NArchive { -namespace NCab { - -static const UInt32 kDataBlockHeaderSize = 8; -/* -struct CDataBlockHeader -{ - UInt32 CheckSum; // checksum of this CFDATA entry - UInt16 PackSize; // number of compressed bytes in this block - UInt16 UnPackSize; // number of uncompressed bytes in this block - // Byte abReserve[]; // (optional) per-datablock reserved area - // Byte ab[cbData]; // compressed data bytes -}; -*/ - -class CTempCabInBuffer -{ -public: - Byte *Buffer; - UInt32 Size; - UInt32 Pos; - Byte ReadByte() - { - if (Pos >= Size) - throw "overflow"; - return Buffer[Pos++]; - } - UInt32 ReadUInt32() - { - UInt32 value = 0; - for (int i = 0; i < 4; i++) - value |= (((UInt32)ReadByte()) << (8 * i)); - return value; - } - UInt16 ReadUInt16() - { - UInt16 value = 0; - for (int i = 0; i < 2; i++) - value |= (((UInt16)ReadByte()) << (8 * i)); - return value; - } -}; - -bool CInBuffer::Create(UInt32 bufferSize) -{ - const UInt32 kMinBlockSize = 1; - if (bufferSize < kMinBlockSize) - bufferSize = kMinBlockSize; - if (m_Buffer != 0 && m_BufferSize == bufferSize) - return true; - Free(); - m_BufferSize = bufferSize; - m_Buffer = (Byte *)::BigAlloc(bufferSize); - return (m_Buffer != 0); -} - -void CInBuffer::Free() -{ - BigFree(m_Buffer); - m_Buffer = 0; -} - -void CInBuffer::Init(Byte reservedSize, UInt32 numBlocks) -{ - m_ReservedSize = reservedSize; - m_NumBlocks = numBlocks; - m_CurrentBlockIndex = 0; - m_ProcessedSize = 0; - m_Pos = 0; - m_NumReadBytesInBuffer = 0; -} - -class CCheckSum -{ - UInt32 m_Value; -public: - CCheckSum(): m_Value(0){}; - void Init() { m_Value = 0; } - void Update(const void *data, UInt32 size); - void UpdateUInt32(UInt32 v) { m_Value ^= v; } - UInt32 GetResult() const { return m_Value; } -}; - -void CCheckSum::Update(const void *data, UInt32 size) -{ - UInt32 checkSum = m_Value; - const Byte *dataPointer = (const Byte *)data; - int numUINT32Words = size / 4; // Number of ULONGs - - UInt32 temp; - while (numUINT32Words-- > 0) - { - temp = *dataPointer++; - temp |= (((UInt32)(*dataPointer++)) << 8); - temp |= (((UInt32)(*dataPointer++)) << 16); - temp |= (((UInt32)(*dataPointer++)) << 24); - checkSum ^= temp; - } - - temp = 0; - int rem = (size & 3); - if (rem >= 3) - temp |= (((UInt32)(*dataPointer++)) << 16); - if (rem >= 2) - temp |= (((UInt32)(*dataPointer++)) << 8); - if (rem >= 1) - temp |= *dataPointer++; - checkSum ^= temp; - m_Value = checkSum; -} - -HRESULT CInBuffer::ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) -{ - if (m_CurrentBlockIndex >= m_NumBlocks) - throw "there is no more data blocks"; - - m_ProcessedSize += m_NumReadBytesInBuffer; - - Byte buffer[kDataBlockHeaderSize]; - UInt32 numProcessedBytes; - RINOK(m_Stream->Read(buffer, kDataBlockHeaderSize, &numProcessedBytes)); - if (numProcessedBytes != kDataBlockHeaderSize) - throw "bad block"; - - CTempCabInBuffer inBuffer; - inBuffer.Size = kDataBlockHeaderSize; - inBuffer.Buffer = (Byte *)buffer; - inBuffer.Pos = 0; - - UInt32 checkSum = inBuffer.ReadUInt32(); // checksum of this CFDATA entry - UInt16 packSize = inBuffer.ReadUInt16(); // number of compressed bytes in this block - UInt16 unPackSize = inBuffer.ReadUInt16(); // number of uncompressed bytes in this block - - if (m_ReservedSize != 0) - { - Byte reservedArea[256]; - RINOK(m_Stream->Read(reservedArea, m_ReservedSize, &numProcessedBytes)); - if (numProcessedBytes != m_ReservedSize) - throw "bad block"; - } - - RINOK(m_Stream->Read(m_Buffer, packSize, &m_NumReadBytesInBuffer)); - if (m_NumReadBytesInBuffer != packSize) - throw "bad block"; - - // Cab specification: - // checkSum: May be set to zero if the checksum is not supplied. - // but seems it's stupid rule. - if (checkSum == 0) - dataAreCorrect = true; - else - { - CCheckSum checkSumCalc; - checkSumCalc.Update(m_Buffer, packSize); - checkSumCalc.UpdateUInt32(packSize | (((UInt32)unPackSize) << 16)); - dataAreCorrect = (checkSumCalc.GetResult() == checkSum); - } - - m_Pos = 0; - uncompressedSize = unPackSize; - - m_CurrentBlockIndex++; - return S_OK; -} - -}} diff --git a/7zip/Archive/Cab/CabInBuffer.h b/7zip/Archive/Cab/CabInBuffer.h deleted file mode 100755 index 1b94f77f..00000000 --- a/7zip/Archive/Cab/CabInBuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -// Archive/CabInBuffer.h - -#ifndef __ARCHIVE_CAB_INBUFFER_H -#define __ARCHIVE_CAB_INBUFFER_H - -#include "../../IStream.h" -#include "../../../Common/MyCom.h" - -namespace NArchive { -namespace NCab { - -class CInBuffer -{ - UInt64 m_ProcessedSize; - UInt32 m_Pos; - UInt32 m_NumReadBytesInBuffer; - Byte *m_Buffer; - CMyComPtr<ISequentialInStream> m_Stream; - UInt32 m_BufferSize; - - UInt32 m_NumBlocks; - UInt32 m_CurrentBlockIndex; - UInt32 m_ReservedSize; - -public: - CInBuffer(): m_Buffer(0) {} - ~CInBuffer() { Free(); } - bool Create(UInt32 bufferSize); - void Free(); - - void SetStream(ISequentialInStream *inStream) { m_Stream = inStream; } - void ReleaseStream() { m_Stream.Release(); } - - void Init(Byte reservedSize, UInt32 numBlocks); - void Init() {} - - bool ReadByte(Byte &b) - { - if(m_Pos >= m_NumReadBytesInBuffer) - return false; - b = m_Buffer[m_Pos++]; - return true; - } - Byte ReadByte() - { - if(m_Pos >= m_NumReadBytesInBuffer) - return 0; - return m_Buffer[m_Pos++]; - } - /* - void ReadBytes(void *data, UInt32 size, UInt32 &aProcessedSize) - { - Byte *aDataPointer = (Byte *)data; - for(int i = 0; i < size; i++) - if (!ReadByte(aDataPointer[i])) - break; - aProcessedSize = i; - } - */ - HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect); - UInt64 GetProcessedSize() const { return m_ProcessedSize + m_Pos; } -}; - -}} - -#endif diff --git a/7zip/Archive/Cab/CabItem.h b/7zip/Archive/Cab/CabItem.h index b1ebeb60..d8b56325 100755 --- a/7zip/Archive/Cab/CabItem.h +++ b/7zip/Archive/Cab/CabItem.h @@ -1,7 +1,7 @@ -// Archive/Cab/ItemInfo.h +// Archive/CabItem.h -#ifndef __ARCHIVE_RAR_ITEMINFO_H -#define __ARCHIVE_RAR_ITEMINFO_H +#ifndef __ARCHIVE_CAB_ITEM_H +#define __ARCHIVE_CAB_ITEM_H #include "Common/Types.h" #include "Common/String.h" @@ -10,23 +10,53 @@ namespace NArchive { namespace NCab { +struct CFolder +{ + UInt32 DataStart; // offset of the first CFDATA block in this folder + UInt16 NumDataBlocks; // number of CFDATA blocks in this folder + Byte CompressionTypeMajor; + Byte CompressionTypeMinor; + Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); } +}; + class CItem { public: - UInt16 Flags; - UInt64 UnPackSize; - UInt32 UnPackOffset; - UInt16 FolderIndex; + AString Name; + UInt32 Offset; + UInt32 Size; UInt32 Time; - UInt16 Attributes; - UInt32 GetWinAttributes() const { return Attributes & (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } + UInt16 FolderIndex; + UInt16 Flags; + UInt16 Attributes; + UInt64 GetEndOffset() const { return (UInt64)Offset + Size; } + UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); } bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; } bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } - AString Name; + + bool ContinuedFromPrev() const + { + return + (FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) || + (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); + } + bool ContinuedToNext() const + { + return + (FolderIndex == NHeader::NFolderIndex::kContinuedToNext) || + (FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext); + } + + int GetFolderIndex(int numFolders) const + { + if (ContinuedFromPrev()) + return 0; + if (ContinuedToNext()) + return (numFolders - 1); + return FolderIndex; + } }; }} #endif - - diff --git a/7zip/Archive/Cab/DllExports.cpp b/7zip/Archive/Cab/DllExports.cpp index b92504fd..fa17f10b 100755 --- a/7zip/Archive/Cab/DllExports.cpp +++ b/7zip/Archive/Cab/DllExports.cpp @@ -8,12 +8,12 @@ #include "CabHandler.h" #include "../../ICoder.h" -// {23170F69-40C1-278A-1000-000110060000} +// {23170F69-40C1-278A-1000-000110080000} DEFINE_GUID(CLSID_CCabHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00); extern "C" -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return TRUE; } diff --git a/7zip/Archive/Cab/LZXBitDecoder.h b/7zip/Archive/Cab/LZXBitDecoder.h deleted file mode 100755 index 51737135..00000000 --- a/7zip/Archive/Cab/LZXBitDecoder.h +++ /dev/null @@ -1,111 +0,0 @@ -// Archive/Cab/LZXBitDecoder.h - -#ifndef __ARCHIVE_CAB_LZXBITDECODER_H -#define __ARCHIVE_CAB_LZXBITDECODER_H - -#include "CabInBuffer.h" - -namespace NArchive { -namespace NCab { -namespace NLZX { -namespace NBitStream { - -const int kNumBigValueBits = 8 * 4; - -const int kNumValueBits = 17; -const int kBitDecoderValueMask = (1 << kNumValueBits) - 1; - -class CDecoder -{ -protected: - CInBuffer m_Stream; - UInt32 m_BitPos; - UInt32 m_Value; -public: - bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } - void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); } - void ReleaseStream() { m_Stream.ReleaseStream(); } - void Init(Byte reservedSize, UInt32 numBlocks) - { - m_Stream.Init(reservedSize, numBlocks); - } - UInt64 GetProcessedSize() const - { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } - UInt32 GetBitPosition() const - { return UInt32(m_Stream.GetProcessedSize() * 8 - (kNumBigValueBits - m_BitPos)); } - - void Init() - { - m_BitPos = kNumBigValueBits; - Normalize(); - } - - void Normalize() - { - for (;m_BitPos >= 16; m_BitPos -= 16) - { - Byte b0 = m_Stream.ReadByte(); - Byte b1 = m_Stream.ReadByte(); - m_Value = (m_Value << 8) | b1; - m_Value = (m_Value << 8) | b0; - } - } - - UInt32 GetValue(UInt32 numBits) - { - return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> - (kNumValueBits - numBits); - } - - void MovePos(UInt32 numBits) - { - m_BitPos += numBits; - Normalize(); - } - - UInt32 ReadBits(UInt32 numBits) - { - UInt32 res = GetValue(numBits); - MovePos(numBits); - return res; - } - UInt32 ReadBitsBig(UInt32 numBits) - { - UInt32 numBits0 = numBits / 2; - UInt32 numBits1 = numBits - numBits0; - UInt32 res = ReadBits(numBits0) << numBits1; - return res + ReadBits(numBits1); - } - - Byte DirectReadByte() - { - if (m_BitPos == kNumBigValueBits) - return m_Stream.ReadByte(); - Byte res; - switch(m_BitPos) - { - case 0: - res = Byte(m_Value >> 16); - break; - case 8: - res = Byte(m_Value >> 24); - break; - case 16: - res = Byte(m_Value); - break; - case 24: - res = Byte(m_Value >> 8); - break; - } - m_BitPos += 8; - return res; - } - - HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) - { return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); } -}; - - -}}}} - -#endif diff --git a/7zip/Archive/Cab/LZXConst.h b/7zip/Archive/Cab/LZXConst.h deleted file mode 100755 index f4648024..00000000 --- a/7zip/Archive/Cab/LZXConst.h +++ /dev/null @@ -1,110 +0,0 @@ -// Archive/Cab/LZXConst.h - -#ifndef __ARCHIVE_CAB_LZXCONST_H -#define __ARCHIVE_CAB_LZXCONST_H - -#include "LZXExtConst.h" - -namespace NArchive { -namespace NCab { -namespace NLZX { - -namespace NBlockType -{ - const int kNumBits = 3; - enum EEnum - { - kVerbatim = 1, - kAligned = 2, - kUncompressed = 3 - }; -} - -const int kUncompressedBlockSizeNumBits = 24; - -const UInt32 kLevelTableSize = 20; - -const UInt32 kNumBitsForPreTreeLevel = 4; - -const int kLevelSymbolZeros = 17; -const int kLevelSymbolZerosBig = 18; -const int kLevelSymbolSame = 19; - -const int kLevelSymbolZerosStartValue = 4; -const int kLevelSymbolZerosNumBits = 4; - -const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue + - (1 << kLevelSymbolZerosNumBits); -const int kLevelSymbolZerosBigNumBits = 5; - -const int kNumBitsForAlignLevel = 3; - -const int kLevelSymbolSameNumBits = 1; -const int kLevelSymbolSameStartValue = 4; - -// const UInt32 kMainTableSize = 256 + kNumPosLenSlots + 1; - -/* -const UInt32 kLenTableSize = 28; - -const UInt32 kLenTableStart = kMainTableSize; -const UInt32 kAlignTableStart = kLenTableStart + kLenTableSize; - -const UInt32 kHeapTablesSizesSum = kMainTableSize + kLenTableSize + kAlignTableSize; - - -const UInt32 kMaxTableSize = kHeapTablesSizesSum; - -const UInt32 kTableDirectLevels = 16; -const UInt32 kTableLevelRepNumber = kTableDirectLevels; -const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; - -const UInt32 kLevelMask = 0xF; - -const UInt32 kPosLenNumber = 256; -const UInt32 kReadTableNumber = 256 + kNumPosLenSlots; - -//const UInt32 kMatchNumber = kReadTableNumber + 1; - -const Byte kLenStart[kLenTableSize] = - {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; -const Byte kLenDirectBits[kLenTableSize] = - {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; -*/ - -const UInt32 kDistStart[] = -{ 0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024, - 1536,2048,3072,4096,6144,8192,12288,16384,24576,32768,49152,65536,98304,131072,196608, - 0x40000, - 0x60000, - 0x80000, - 0xA0000, - 0xC0000, - 0xE0000, - - 0x100000, - 0x120000, - 0x140000, - 0x160000, - 0x180000, - 0x1A0000, - 0x1C0000, - 0x1E0000 -}; -const Byte kDistDirectBits[] = -{ - 0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16, - 17, 17, 17, 17, 17, 17, - 17, 17,17, 17, 17, 17, 17, 17 -}; - -/* -const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; - -const UInt32 kDistLimit2 = 0x101 - 1; -*/ - -}}} - -#endif diff --git a/7zip/Archive/Cab/LZXDecoder.cpp b/7zip/Archive/Cab/LZXDecoder.cpp deleted file mode 100755 index 49f87ed7..00000000 --- a/7zip/Archive/Cab/LZXDecoder.cpp +++ /dev/null @@ -1,310 +0,0 @@ -// Archive/Cab/LZXDecoder.cpp - -#include "StdAfx.h" - -#include "LZXDecoder.h" - -#include "Common/Defs.h" -#include "Windows/Defs.h" - -namespace NArchive { -namespace NCab { -namespace NLZX { - -static const UInt32 kHistorySize = (1 << 21); - -CDecoder::CDecoder() -{ - m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream; - m_i86TranslationOutStream = m_i86TranslationOutStreamSpec; -} - -void CDecoder::ReleaseStreams() -{ - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - m_i86TranslationOutStreamSpec->ReleaseStream(); -} - -STDMETHODIMP CDecoder::Flush() -{ - RINOK(m_OutWindowStream.Flush()); - return m_i86TranslationOutStreamSpec->Flush(); -} - -void CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols) -{ - Byte levelLevels[kLevelTableSize]; - UInt32 i; - for (i = 0; i < kLevelTableSize; i++) - levelLevels[i] = Byte(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel)); - m_LevelDecoder.SetCodeLengths(levelLevels); - for (i = 0; i < numSymbols;) - { - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); - if (number <= kNumHuffmanBits) - newLevels[i++] = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); - else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig) - { - int num; - if (number == kLevelSymbolZeros) - num = kLevelSymbolZerosStartValue + - m_InBitStream.ReadBits(kLevelSymbolZerosNumBits); - else - num = kLevelSymbolZerosBigStartValue + - m_InBitStream.ReadBits(kLevelSymbolZerosBigNumBits); - for (;num > 0 && i < numSymbols; num--, i++) - newLevels[i] = 0; - } - else if (number == kLevelSymbolSame) - { - int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits); - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); - if (number > kNumHuffmanBits) - throw "bad data"; - Byte symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); - for (; num > 0 && i < numSymbols; num--, i++) - newLevels[i] = symbol; - } - else - throw "bad data"; - } - - memmove(lastLevels, newLevels, numSymbols); -} - -void CDecoder::ReadTables(void) -{ - int blockType = m_InBitStream.ReadBits(NBlockType::kNumBits); - - if (blockType != NBlockType::kVerbatim && blockType != NBlockType::kAligned && - blockType != NBlockType::kUncompressed) - throw "bad data"; - - m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits); - - if (blockType == NBlockType::kUncompressed) - { - m_UncompressedBlock = true; - UInt32 bitPos = m_InBitStream.GetBitPosition() % 16; - m_InBitStream.ReadBits(16 - bitPos); - for (int i = 0; i < kNumRepDistances; i++) - { - m_RepDistances[i] = 0; - for (int j = 0; j < 4; j++) - m_RepDistances[i] |= (m_InBitStream.DirectReadByte()) << (8 * j); - m_RepDistances[i]--; - } - return; - } - - m_UncompressedBlock = false; - - m_AlignIsUsed = (blockType == NBlockType::kAligned); - - Byte newLevels[kMaxTableSize]; - - if (m_AlignIsUsed) - { - for(int i = 0; i < kAlignTableSize; i++) - newLevels[i] = m_InBitStream.ReadBits(kNumBitsForAlignLevel); - m_AlignDecoder.SetCodeLengths(newLevels); - } - - ReadTable(m_LastByteLevels, newLevels, 256); - ReadTable(m_LastPosLenLevels, newLevels + 256, m_NumPosLenSlots); - for (int i = m_NumPosLenSlots; i < kNumPosSlotLenSlotSymbols; i++) - newLevels[256 + i] = 0; - m_MainDecoder.SetCodeLengths(newLevels); - - ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols); - m_LenDecoder.SetCodeLengths(newLevels); - -} - -class CDecoderFlusher -{ - CDecoder *m_Decoder; -public: - CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder) {} - ~CDecoderFlusher() - { - m_Decoder->Flush(); - m_Decoder->ReleaseStreams(); - } -}; - - -void CDecoder::ClearPrevLeveles() -{ - memset(m_LastByteLevels, 0, 256); - memset(m_LastPosLenLevels, 0, kNumPosSlotLenSlotSymbols); - memset(m_LastLenLevels, 0, kNumLenSymbols); -}; - - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - if (outSize == NULL) - return E_INVALIDARG; - UInt64 size = *outSize; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_OutWindowStream.SetStream(m_i86TranslationOutStream); - m_OutWindowStream.Init(); - - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(m_ReservedSize, m_NumInDataBlocks); - - CDecoderFlusher flusher(this); - - UInt32 uncompressedCFDataBlockSize; - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - UInt32 uncompressedCFDataCurrentValue = 0; - m_InBitStream.Init(); - - ClearPrevLeveles(); - - if (m_InBitStream.ReadBits(1) == 0) - m_i86TranslationOutStreamSpec->Init(outStream, false, 0); - else - { - UInt32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16; - i86TranslationSize |= m_InBitStream.ReadBits(16); - m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize); - } - - for(int i = 0 ; i < kNumRepDistances; i++) - m_RepDistances[i] = 0; - - UInt64 nowPos64 = 0; - while(nowPos64 < size) - { - if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) - { - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - m_InBitStream.Init(); - uncompressedCFDataCurrentValue = 0; - } - ReadTables(); - UInt32 nowPos = 0; - UInt32 next = (UInt32)MyMin((UInt64)m_UnCompressedBlockSize, size - nowPos64); - if (m_UncompressedBlock) - { - while(nowPos < next) - { - m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte()); - nowPos++; - uncompressedCFDataCurrentValue++; - if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) - { - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - // m_InBitStream.Init(); - uncompressedCFDataCurrentValue = 0; - continue; - } - } - int bitPos = m_InBitStream.GetBitPosition() % 16; - if (bitPos == 8) - m_InBitStream.DirectReadByte(); - m_InBitStream.Normalize(); - } - else for (;nowPos < next;) - { - if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) - { - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - m_InBitStream.Init(); - uncompressedCFDataCurrentValue = 0; - } - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); - if (number < 256) - { - m_OutWindowStream.PutByte(Byte(number)); - nowPos++; - uncompressedCFDataCurrentValue++; - // continue; - } - else if (number < 256 + m_NumPosLenSlots) - { - UInt32 posLenSlot = number - 256; - UInt32 posSlot = posLenSlot / kNumLenSlots; - UInt32 lenSlot = posLenSlot % kNumLenSlots; - UInt32 length = 2 + lenSlot; - if (lenSlot == kNumLenSlots - 1) - length += m_LenDecoder.DecodeSymbol(&m_InBitStream); - - if (posSlot < kNumRepDistances) - { - UInt32 distance = m_RepDistances[posSlot]; - m_OutWindowStream.CopyBlock(distance, length); - if (posSlot != 0) - { - m_RepDistances[posSlot] = m_RepDistances[0]; - m_RepDistances[0] = distance; - } - } - else - { - UInt32 pos = kDistStart[posSlot]; - UInt32 posDirectBits = kDistDirectBits[posSlot]; - if (m_AlignIsUsed && posDirectBits >= kNumAlignBits) - { - pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits); - pos += m_AlignDecoder.DecodeSymbol(&m_InBitStream); - } - else - pos += m_InBitStream.ReadBits(posDirectBits); - UInt32 distance = pos - kNumRepDistances; - if (distance >= nowPos64 + nowPos) - throw 777123; - m_OutWindowStream.CopyBlock(distance, length); - m_RepDistances[2] = m_RepDistances[1]; - m_RepDistances[1] = m_RepDistances[0]; - m_RepDistances[0] = distance; - } - nowPos += length; - uncompressedCFDataCurrentValue += length; - } - else - throw 98112823; - } - if (progress != NULL) - { - UInt64 inSize = m_InBitStream.GetProcessedSize(); - UInt64 outSize = nowPos64 + nowPos; - RINOK(progress->SetRatioInfo(&inSize, &outSize)); - } - nowPos64 += nowPos; - } - return S_OK; -} - -}}} diff --git a/7zip/Archive/Cab/LZXDecoder.h b/7zip/Archive/Cab/LZXDecoder.h deleted file mode 100755 index 257de7b9..00000000 --- a/7zip/Archive/Cab/LZXDecoder.h +++ /dev/null @@ -1,95 +0,0 @@ -// Archive/Cab/LZXDecoder.h - -#ifndef __ARCHIVE_CAB_LZXDECODER_H -#define __ARCHIVE_CAB_LZXDECODER_H - -#include "../../ICoder.h" - -#include "../../Compress/Huffman/HuffmanDecoder.h" -#include "../../Compress/LZ/LZOutWindow.h" - -#include "LZXExtConst.h" -#include "LZXBitDecoder.h" - -#include "LZXi86Converter.h" -#include "LZXConst.h" - -namespace NArchive { -namespace NCab { -namespace NLZX { - -const int kMainTableSize = 256 + kNumPosSlotLenSlotSymbols; - -class CDecoder : - public ICompressCoder, - public CMyUnknownImp -{ - CLZOutWindow m_OutWindowStream; - NBitStream::CDecoder m_InBitStream; - - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; - - UInt32 m_RepDistances[kNumRepDistances]; - - Byte m_LastByteLevels[256]; - Byte m_LastPosLenLevels[kNumPosSlotLenSlotSymbols]; - Byte m_LastLenLevels[kNumLenSymbols]; - - UInt32 m_DictionarySizePowerOf2; - UInt32 m_NumPosSlots; - UInt32 m_NumPosLenSlots; - - // bool m_i86PreprocessingUsed; - // UInt32 m_i86TranslationSize; - - bool m_UncompressedBlock; - bool m_AlignIsUsed; - - UInt32 m_UnCompressedBlockSize; - - Ci86TranslationOutStream *m_i86TranslationOutStreamSpec; - CMyComPtr<ISequentialOutStream> m_i86TranslationOutStream; - - Byte m_ReservedSize; - UInt32 m_NumInDataBlocks; - - void ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols); - void ReadTables(); - void ClearPrevLeveles(); - -public: - CDecoder(); - - MY_UNKNOWN_IMP - - void ReleaseStreams(); - STDMETHOD(Flush)(); - - // ICompressCoder interface - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - void SetParams(Byte reservedSize, UInt32 numInDataBlocks, - UInt32 dictionarySizePowerOf2) - { - m_ReservedSize = reservedSize; - m_NumInDataBlocks = numInDataBlocks; - m_DictionarySizePowerOf2 = dictionarySizePowerOf2; - if (dictionarySizePowerOf2 < 20) - m_NumPosSlots = 30 + (dictionarySizePowerOf2 - 15) * 2; - else if (dictionarySizePowerOf2 == 20) - m_NumPosSlots = 42; - else - m_NumPosSlots = 50; - m_NumPosLenSlots = m_NumPosSlots * kNumLenSlots; - } -}; - -}}} - -#endif
\ No newline at end of file diff --git a/7zip/Archive/Cab/LZXExtConst.h b/7zip/Archive/Cab/LZXExtConst.h deleted file mode 100755 index df2ef6cf..00000000 --- a/7zip/Archive/Cab/LZXExtConst.h +++ /dev/null @@ -1,30 +0,0 @@ -// Archive/Cab/LZXExtConst.h - -#ifndef __ARCHIVE_CAB_LZXEXTCONST_H -#define __ARCHIVE_CAB_LZXEXTCONST_H - -namespace NArchive { -namespace NCab { -namespace NLZX { - -const UInt32 kNumRepDistances = 3; - -const UInt32 kNumLenSlots = 8; -const UInt32 kMatchMinLen = 2; -const UInt32 kNumLenSymbols = 249; -const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; - -const Byte kNumAlignBits = 3; -const UInt32 kAlignTableSize = 1 << kNumAlignBits; - -const UInt32 kNumHuffmanBits = 16; - -const int kNumPosSlotSymbols = 50; -const int kNumPosSlotLenSlotSymbols = kNumPosSlotSymbols * kNumLenSlots; - -const int kMaxTableSize = 256 + kNumPosSlotLenSlotSymbols; - - -}}} - -#endif diff --git a/7zip/Archive/Cab/MSZipConst.h b/7zip/Archive/Cab/MSZipConst.h deleted file mode 100755 index f2dfda86..00000000 --- a/7zip/Archive/Cab/MSZipConst.h +++ /dev/null @@ -1,92 +0,0 @@ -// MSZipConst.h - -#ifndef __MSZIP_CONST_H -#define __MSZIP_CONST_H - -#include "MSZipExtConst.h" - -namespace NArchive { -namespace NCab { -namespace NMSZip { - -const UInt32 kLenTableSize = 29; - -const UInt32 kStaticDistTableSize = 32; -const UInt32 kStaticLenTableSize = 31; - -const UInt32 kReadTableNumber = 0x100; -const UInt32 kMatchNumber = kReadTableNumber + 1; - -const UInt32 kMainTableSize = kMatchNumber + kLenTableSize; //298; -const UInt32 kStaticMainTableSize = kMatchNumber + kStaticLenTableSize; //298; - -const UInt32 kDistTableStart = kMainTableSize; - -const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize; - -const UInt32 kLevelTableSize = 19; - -const UInt32 kMaxTableSize = kHeapTablesSizesSum; // test it -const UInt32 kStaticMaxTableSize = kStaticMainTableSize + kStaticDistTableSize; - -const UInt32 kTableDirectLevels = 16; -const UInt32 kTableLevelRepNumber = kTableDirectLevels; -const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; -const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; - -const UInt32 kLevelMask = 0xF; - -const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255}; -const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; - - -const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576}; -const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; - -const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; - -const Byte kCodeLengthAlphabetOrder[kLevelTableSize] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -const UInt32 kMatchMinLen = 3; -const UInt32 kMatchMaxLen = kNumLenCombinations + kMatchMinLen - 1; //255 + 2; test it - -const int kFinalBlockFieldSize = 1; - -namespace NFinalBlockField -{ -enum -{ - kNotFinalBlock = 0, - kFinalBlock = 1 -}; -} - -const int kBlockTypeFieldSize = 2; - -namespace NBlockType -{ - enum - { - kStored = 0, - kFixedHuffman = 1, - kDynamicHuffman = 2, - kReserved = 3 - }; -} - -const UInt32 kDeflateNumberOfLengthCodesFieldSize = 5; -const UInt32 kDeflateNumberOfDistanceCodesFieldSize = 5; -const UInt32 kDeflateNumberOfLevelCodesFieldSize = 4; - -const UInt32 kDeflateNumberOfLitLenCodesMin = 257; - -const UInt32 kDeflateNumberOfDistanceCodesMin = 1; -const UInt32 kDeflateNumberOfLevelCodesMin = 4; - -const UInt32 kDeflateLevelCodeFieldSize = 3; - -const UInt32 kDeflateStoredBlockLengthFieldSizeSize = 16; - -}}} - -#endif
\ No newline at end of file diff --git a/7zip/Archive/Cab/MSZipDecoder.cpp b/7zip/Archive/Cab/MSZipDecoder.cpp deleted file mode 100755 index 9e004bf9..00000000 --- a/7zip/Archive/Cab/MSZipDecoder.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// Archive/Cab/MSZipDecoder.cpp - -#include "StdAfx.h" - -#include "MSZipDecoder.h" - -#include "Windows/Defs.h" - -namespace NArchive { -namespace NCab { -namespace NMSZip { - -CDecoder::CDecoder(){} - -HRESULT CDecoder::Flush() -{ - return m_OutWindowStream.Flush(); -} - -void CDecoder::ReleaseStreams() -{ - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); -} - -void CDecoder::DeCodeLevelTable(Byte *newLevels, int numLevels) -{ - int i = 0; - while (i < numLevels) - { - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); - if (number < kTableDirectLevels) - newLevels[i++] = Byte(number); - else - { - if (number == kTableLevelRepNumber) - { - int t = m_InBitStream.ReadBits(2) + 3; - for (int reps = t; reps > 0 && i < numLevels ; reps--, i++) - newLevels[i] = newLevels[i - 1]; - } - else - { - int num; - if (number == kTableLevel0Number) - num = m_InBitStream.ReadBits(3) + 3; - else - num = m_InBitStream.ReadBits(7) + 11; - for (;num > 0 && i < numLevels; num--) - newLevels[i++] = 0; - } - } - } -} - -void CDecoder::ReadTables(void) -{ - if(m_FinalBlock) // test it - throw CDecoderException(CDecoderException::kData); - - m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); - - int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize); - - switch(blockType) - { - case NBlockType::kStored: - { - m_StoredMode = true; - UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); - UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; - if (numBitsForAlign > 0) - m_InBitStream.ReadBits(numBitsForAlign); - m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize); - WORD onesComplementReverse = ~WORD(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize)); - if (m_StoredBlockSize != onesComplementReverse) - throw CDecoderException(CDecoderException::kData); - break; - } - case NBlockType::kFixedHuffman: - case NBlockType::kDynamicHuffman: - { - m_StoredMode = false; - Byte litLenLevels[kStaticMainTableSize]; - Byte distLevels[kStaticDistTableSize]; - if (blockType == NBlockType::kFixedHuffman) - { - int i; - - // Leteral / length levels - for (i = 0; i < 144; i++) - litLenLevels[i] = 8; - for (; i < 256; i++) - litLenLevels[i] = 9; - for (; i < 280; i++) - litLenLevels[i] = 7; - for (; i < 288; i++) /* make a complete, but wrong code set */ - litLenLevels[i] = 8; - - // Distance levels - for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize - distLevels[i] = 5; - } - else // in case when (blockType == kDeflateBlockTypeFixedHuffman) - { - int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) + - kDeflateNumberOfLitLenCodesMin; - int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) + - kDeflateNumberOfDistanceCodesMin; - int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) + - kDeflateNumberOfLevelCodesMin; - - int numLevels; - numLevels = kHeapTablesSizesSum; - - Byte levelLevels[kLevelTableSize]; - int i; - for (i = 0; i < kLevelTableSize; i++) - { - int position = kCodeLengthAlphabetOrder[i]; - if(i < numLevelCodes) - levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); - else - levelLevels[position] = 0; - } - - try - { - m_LevelDecoder.SetCodeLengths(levelLevels); - } - catch(...) - { - throw CDecoderException(CDecoderException::kData); - } - - Byte tmpLevels[kStaticMaxTableSize]; - DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels); - - memmove(litLenLevels, tmpLevels, numLitLenLevels); - memset(litLenLevels + numLitLenLevels, 0, - kStaticMainTableSize - numLitLenLevels); - - memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels); - memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels); - } - try - { - m_MainDecoder.SetCodeLengths(litLenLevels); - m_DistDecoder.SetCodeLengths(distLevels); - } - catch(...) - { - throw CDecoderException(CDecoderException::kData); - } - break; - } - default: - throw CDecoderException(CDecoderException::kData); - } -} - -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *aCoder): m_Coder(aCoder) {} - ~CCoderReleaser() - { - m_Coder->Flush(); - m_Coder->ReleaseStreams(); - } -}; - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - if (outSize == NULL) - return E_INVALIDARG; - UInt64 size = *outSize; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - - m_InBitStream.SetStream(inStream); - m_InBitStream.InitMain(m_ReservedSize, m_NumInDataBlocks); - CCoderReleaser coderReleaser(this); - - UInt64 nowPos = 0; - while(nowPos < size) - { - if (progress != NULL) - { - UInt64 packSize = m_InBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &nowPos)); - } - UInt32 uncompressedCFDataBlockSize; - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - m_InBitStream.Init(); - if (m_InBitStream.ReadBits(8) != 0x43) - throw CDecoderException(CDecoderException::kData); - if (m_InBitStream.ReadBits(8) != 0x4B) - throw CDecoderException(CDecoderException::kData); - UInt32 uncompressedCFDataCurrentValue = 0; - m_FinalBlock = false; - while (uncompressedCFDataCurrentValue < uncompressedCFDataBlockSize) - { - ReadTables(); - if(m_StoredMode) - { - for (UInt32 i = 0; i < m_StoredBlockSize; i++) - m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8))); - nowPos += m_StoredBlockSize; - uncompressedCFDataCurrentValue += m_StoredBlockSize; - continue; - } - while(true) - { - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); - - if (number < 256) - { - m_OutWindowStream.PutByte(Byte(number)); - nowPos++; - uncompressedCFDataCurrentValue++; - continue; - } - else if (number >= kMatchNumber) - { - number -= kMatchNumber; - UInt32 length = UInt32(kLenStart[number]) + kMatchMinLen; - UInt32 numBits; - if ((numBits = kLenDirectBits[number]) > 0) - length += m_InBitStream.ReadBits(numBits); - - number = m_DistDecoder.DecodeSymbol(&m_InBitStream); - UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); - /* - if (distance >= nowPos) - throw "data error"; - */ - m_OutWindowStream.CopyBlock(distance, length); - nowPos += length; - uncompressedCFDataCurrentValue += length; - } - else if (number == kReadTableNumber) - { - break; - } - else - throw CDecoderException(CDecoderException::kData); - } - } - } - return S_OK; -} - -}}} diff --git a/7zip/Archive/Cab/MSZipDecoder.h b/7zip/Archive/Cab/MSZipDecoder.h deleted file mode 100755 index f83a5ab7..00000000 --- a/7zip/Archive/Cab/MSZipDecoder.h +++ /dev/null @@ -1,85 +0,0 @@ -// Archive/Cab/MSZipDecoder.h - -#ifndef __ARCHIVE_CAB_DECODER_H -#define __ARCHIVE_CAB_DECODER_H - -#include "Common/MyCom.h" -#include "../../ICoder.h" -#include "../../Common/LSBFDecoder.h" -#include "../../Compress/Huffman/HuffmanDecoder.h" -#include "../../Compress/LZ/LZOutWindow.h" - -#include "CabInBuffer.h" -#include "MSZipExtConst.h" -#include "MSZipConst.h" - -namespace NArchive { -namespace NCab { -namespace NMSZip { - -class CDecoderException -{ -public: - enum ECauseType - { - kData - } m_Cause; - CDecoderException(ECauseType aCause): m_Cause(aCause) {} -}; - -class CMSZipBitDecoder: public NStream::NLSBF::CDecoder<NCab::CInBuffer> -{ -public: - void InitMain(Byte reservedSize, UInt32 aNumBlocks) - { - m_Stream.Init(reservedSize, aNumBlocks); - Init(); - } - HRESULT ReadBlock(UInt32 &uncompressedSize, bool &dataAreCorrect) - { - return m_Stream.ReadBlock(uncompressedSize, dataAreCorrect); - } -}; - -class CDecoder : - public ICompressCoder, - public CMyUnknownImp -{ - CLZOutWindow m_OutWindowStream; - CMSZipBitDecoder m_InBitStream; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticMainTableSize> m_MainDecoder; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; - - bool m_FinalBlock; - bool m_StoredMode; - UInt32 m_StoredBlockSize; - - Byte m_ReservedSize; - UInt32 m_NumInDataBlocks; - - void DeCodeLevelTable(Byte *newLevels, int numLevels); - void ReadTables(); -public: - CDecoder(); - - MY_UNKNOWN_IMP - - HRESULT Flush(); - void ReleaseStreams(); - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - void SetParams(Byte reservedSize, UInt32 numInDataBlocks) - { - m_ReservedSize = reservedSize; - m_NumInDataBlocks = numInDataBlocks; - } - -}; - -}}} - -#endif
\ No newline at end of file diff --git a/7zip/Archive/Cab/MSZipExtConst.h b/7zip/Archive/Cab/MSZipExtConst.h deleted file mode 100755 index f51eebb8..00000000 --- a/7zip/Archive/Cab/MSZipExtConst.h +++ /dev/null @@ -1,20 +0,0 @@ -// DeflateExtConst.h - -#ifndef __DEFLATEEXTCONST_H -#define __DEFLATEEXTCONST_H - -#include "Common/Types.h" - -namespace NArchive { -namespace NCab { -namespace NMSZip { - - const UInt32 kDistTableSize = 30; - const UInt32 kHistorySize = 0x8000; - const UInt32 kNumLenCombinations = 256; - - const UInt32 kNumHuffmanBits = 15; - -}}} - -#endif diff --git a/7zip/Archive/Cab/makefile b/7zip/Archive/Cab/makefile index ab635c5d..672afed3 100755 --- a/7zip/Archive/Cab/makefile +++ b/7zip/Archive/Cab/makefile @@ -5,14 +5,10 @@ LIBS = $(LIBS) oleaut32.lib user32.lib CAB_OBJS = \ $O\DllExports.obj \ - $O\CabCopyDecoder.obj \ + $O\CabBlockInStream.obj \ $O\CabHandler.obj \ $O\CabHeader.obj \ $O\CabIn.obj \ - $O\CabInBuffer.obj \ - $O\LZXDecoder.obj \ - $O\LZXi86Converter.obj \ - $O\MSZipDecoder.obj \ COMMON_OBJS = \ $O\Alloc.obj \ @@ -32,6 +28,11 @@ WIN_OBJS = \ $O\LSBFDecoder.obj \ $O\OutBuffer.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +COMPRESS_LZX_OBJS = \ + $O\LzxDecoder.obj \ + $O\Lzx86Converter.obj \ OBJS = \ $O\StdAfx.obj \ @@ -39,7 +40,11 @@ OBJS = \ $(COMMON_OBJS) \ $(WIN_OBJS) \ $(7ZIP_COMMON_OBJS) \ + $(COMPRESS_LZX_OBJS) \ + $O\DeflateDecoder.obj \ + $O\QuantumDecoder.obj \ $O\LZOutWindow.obj \ + $O\CopyCoder.obj \ $O\resource.res !include "../../../Build.mak" @@ -52,5 +57,14 @@ $(WIN_OBJS): ../../../Windows/$(*B).cpp $(COMPL) $(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp $(COMPL) +$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp + $(COMPL_O2) +$O\DeflateDecoder.obj: ../../Compress/Deflate/$(*B).cpp + $(COMPL_O2) +$O\QuantumDecoder.obj: ../../Compress/Quantum/$(*B).cpp + $(COMPL) $O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + diff --git a/7zip/Archive/Chm/Chm.dsp b/7zip/Archive/Chm/Chm.dsp new file mode 100755 index 00000000..7e0b7c66 --- /dev/null +++ b/7zip/Archive/Chm/Chm.dsp @@ -0,0 +1,337 @@ +# Microsoft Developer Studio Project File - Name="Chm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Chm - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Chm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Chm.mak" CFG="Chm - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Chm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Chm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Chm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Formats\chm.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Chm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CHM_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Formats\chm.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Chm - Win32 Release" +# Name "Chm - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Archive.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ChmHandler.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChmHandler.h +# End Source File +# Begin Source File + +SOURCE=.\ChmHeader.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChmHeader.h +# End Source File +# Begin Source File + +SOURCE=.\ChmIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\ChmIn.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\LimitedStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# End Group +# Begin Group "Archive Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ItemNameUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Lzx" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.cpp + +!IF "$(CFG)" == "Chm - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Chm - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\Lzx86Converter.h +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.cpp + +!IF "$(CFG)" == "Chm - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Chm - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Lzx\LzxDecoder.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Target +# End Project diff --git a/7zip/Archive/Chm/Chm.dsw b/7zip/Archive/Chm/Chm.dsw new file mode 100755 index 00000000..58cb09b2 --- /dev/null +++ b/7zip/Archive/Chm/Chm.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Chm"=.\Chm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Archive/Chm/ChmHandler.cpp b/7zip/Archive/Chm/ChmHandler.cpp new file mode 100755 index 00000000..3f2d3cc7 --- /dev/null +++ b/7zip/Archive/Chm/ChmHandler.cpp @@ -0,0 +1,729 @@ +// Chm/Handler.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Defs.h" +#include "Common/UTFConvert.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" +#include "Windows/Time.h" + +#include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" +#include "../../Common/ProgressUtils.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Compress/Lzx/LzxDecoder.h" + +#include "../Common/ItemNameUtils.h" + +#include "ChmHandler.h" + + +using namespace NWindows; +using namespace NTime; + +namespace NArchive { +namespace NChm { + +// #define _CHM_DETAILS + +#ifdef _CHM_DETAILS + +enum +{ + kpidSection = kpidUserDefined, + kpidOffset +}; + +#endif + +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidBlock, VT_UI4} + + #ifdef _CHM_DETAILS + , + { L"Section", kpidSection, VT_UI4}, + { L"Offset", kpidOffset, VT_UI4} + #endif +}; + +static const int kNumProperties = sizeof(kProperties) / sizeof(kProperties[0]); + +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; + 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) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant propVariant; + if (m_Database.NewFormat) + { + switch(propID) + { + case kpidSize: + propVariant = (UInt64)m_Database.NewFormatString.Length(); + break; + } + propVariant.Detach(value); + return S_OK; + } + int entryIndex; + if (m_Database.LowLevel) + entryIndex = index; + else + entryIndex = m_Database.Indices[index]; + const CItem &item = m_Database.Items[entryIndex]; + switch(propID) + { + case kpidPath: + { + UString us; + if (ConvertUTF8ToUnicode(item.Name, us)) + { + if (!m_Database.LowLevel) + { + if (us.Length() > 1) + if (us[0] == L'/') + us.Delete(0); + } + propVariant = NItemName::GetOSName2(us); + } + break; + } + case kpidIsFolder: + propVariant = item.IsDirectory(); + break; + case kpidSize: + propVariant = item.Size; + break; + case kpidMethod: + { + if (!item.IsDirectory()) + if (item.Section == 0) + propVariant = L"Copy"; + else if (item.Section < m_Database.Sections.Size()) + propVariant = m_Database.Sections[(size_t)item.Section].GetMethodName(); + break; + } + case kpidBlock: + if (m_Database.LowLevel) + propVariant = item.Section; + else if (item.Section != 0) + propVariant = m_Database.GetFolder(index); + break; + + #ifdef _CHM_DETAILS + + case kpidSection: + propVariant = (UInt32)item.Section; + break; + case kpidOffset: + propVariant = (UInt32)item.Offset; + break; + + #endif + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +class CPropgressImp: public CProgressVirt +{ + CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback; +public: + STDMETHOD(SetTotal)(const UInt64 *numFiles); + STDMETHOD(SetCompleted)(const UInt64 *numFiles); + void Init(IArchiveOpenCallback *openArchiveCallback) + { m_OpenArchiveCallback = openArchiveCallback; } +}; + +STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles) +{ + if (m_OpenArchiveCallback) + return m_OpenArchiveCallback->SetCompleted(numFiles, NULL); + return S_OK; +} + +STDMETHODIMP CHandler::Open(IInStream *inStream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + m_Stream.Release(); + try + { + CInArchive archive; + CPropgressImp progressImp; + progressImp.Init(openArchiveCallback); + RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database)); + /* + if (m_Database.LowLevel) + return S_FALSE; + */ + m_Stream = inStream; + } + catch(...) + { + return S_FALSE; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::Close() +{ + m_Stream.Release(); + return S_OK; +} + +class CChmFolderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + HRESULT Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK); + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + + UInt64 m_FolderSize; + UInt64 m_PosInFolder; + UInt64 m_PosInSection; + const CRecordVector<bool> *m_ExtractStatuses; + int m_StartIndex; + int m_CurrentIndex; + int m_NumFiles; + +private: + const CFilesDatabase *m_Database; + CMyComPtr<IArchiveExtractCallback> m_ExtractCallback; + bool m_TestMode; + + bool m_IsOk; + bool m_FileIsOpen; + UInt64 m_RemainFileSize; + CMyComPtr<ISequentialOutStream> m_RealOutStream; + + HRESULT OpenFile(); + HRESULT WriteEmptyFiles(); +public: + void Init( + const CFilesDatabase *database, + IArchiveExtractCallback *extractCallback, + bool testMode); + HRESULT FlushCorrupted(); +}; + +void CChmFolderOutStream::Init( + const CFilesDatabase *database, + IArchiveExtractCallback *extractCallback, + bool testMode) +{ + m_Database = database; + m_ExtractCallback = extractCallback; + m_TestMode = testMode; + + m_CurrentIndex = 0; + m_FileIsOpen = false; +} + +HRESULT CChmFolderOutStream::OpenFile() +{ + Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract) : + NExtract::NAskMode::kSkip; + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->GetStream(m_StartIndex + m_CurrentIndex, &m_RealOutStream, askMode)); + if (!m_RealOutStream && !m_TestMode) + askMode = NArchive::NExtract::NAskMode::kSkip; + return m_ExtractCallback->PrepareOperation(askMode); +} + +HRESULT CChmFolderOutStream::WriteEmptyFiles() +{ + if (m_FileIsOpen) + return S_OK; + for(;m_CurrentIndex < m_NumFiles; m_CurrentIndex++) + { + UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex); + if (fileSize != 0) + return S_OK; + HRESULT result = OpenFile(); + m_RealOutStream.Release(); + RINOK(result); + RINOK(m_ExtractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + return S_OK; +} + +// This is WritePart function +HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK) +{ + UInt32 realProcessed = 0; + if (processedSize != NULL) + *processedSize = 0; + while(size != 0) + { + if (m_FileIsOpen) + { + UInt32 numBytesToWrite = (UInt32)MyMin(m_RemainFileSize, (UInt64)(size)); + HRESULT res = S_OK; + if (numBytesToWrite > 0) + { + if (!isOK) + m_IsOk = false; + if (m_RealOutStream) + { + UInt32 processedSizeLocal = 0; + res = m_RealOutStream->Write((const Byte *)data, numBytesToWrite, &processedSizeLocal); + numBytesToWrite = processedSizeLocal; + } + } + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_RemainFileSize -= numBytesToWrite; + m_PosInSection += numBytesToWrite; + m_PosInFolder += numBytesToWrite; + if (res != S_OK) + return res; + if (m_RemainFileSize == 0) + { + m_RealOutStream.Release(); + RINOK(m_ExtractCallback->SetOperationResult( + m_IsOk ? + NArchive::NExtract::NOperationResult::kOK: + NArchive::NExtract::NOperationResult::kDataError)); + m_FileIsOpen = false; + } + if (realProcessed > 0) + break; // with this break this function works as write part + } + else + { + if (m_CurrentIndex >= m_NumFiles) + return E_FAIL; + int fullIndex = m_StartIndex + m_CurrentIndex; + m_RemainFileSize = m_Database->GetFileSize(fullIndex); + UInt64 fileOffset = m_Database->GetFileOffset(fullIndex); + if (fileOffset < m_PosInSection) + return E_FAIL; + if (fileOffset > m_PosInSection) + { + UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size)); + realProcessed += numBytesToWrite; + if (processedSize != NULL) + *processedSize = realProcessed; + data = (const void *)((const Byte *)data + numBytesToWrite); + size -= numBytesToWrite; + m_PosInSection += numBytesToWrite; + m_PosInFolder += numBytesToWrite; + } + if (fileOffset == m_PosInSection) + { + RINOK(OpenFile()); + m_FileIsOpen = true; + m_CurrentIndex++; + m_IsOk = true; + } + } + } + return WriteEmptyFiles(); +} + +STDMETHODIMP CChmFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + return Write2(data, size, processedSize, true); +} + +HRESULT CChmFolderOutStream::FlushCorrupted() +{ + const UInt32 kBufferSize = (1 << 10); + Byte buffer[kBufferSize]; + for (int i = 0; i < kBufferSize; i++) + buffer[i] = 0; + while(m_PosInFolder < m_FolderSize) + { + UInt32 size = (UInt32)MyMin(m_FolderSize - m_PosInFolder, (UInt64)kBufferSize); + UInt32 processedSizeLocal = 0; + RINOK(Write2(buffer, size, &processedSizeLocal, false)); + } + return S_OK; +} + + +STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, + Int32 _aTestMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == UInt32(-1)); + + if (allFilesMode) + numItems = m_Database.NewFormat ? 1: + (m_Database.LowLevel ? + m_Database.Items.Size(): + m_Database.Indices.Size()); + if(numItems == 0) + return S_OK; + bool testMode = (_aTestMode != 0); + + UInt64 currentTotalSize = 0; + + CMyComPtr<ICompressCoder> copyCoder; + UInt32 i; + + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> inStream(streamSpec); + + if (m_Database.LowLevel) + { + UInt64 currentItemSize = 0; + UInt64 totalSize = 0; + if (m_Database.NewFormat) + totalSize = m_Database.NewFormatString.Length(); + else + for(i = 0; i < numItems; i++) + totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size; + extractCallback->SetTotal(totalSize); + + for(i = 0; i < numItems; i++, currentTotalSize += currentItemSize) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + CMyComPtr<ISequentialOutStream> realOutStream; + Int32 askMode; + askMode = testMode ? NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + Int32 index = allFilesMode ? i : indices[i]; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + + if (m_Database.NewFormat) + { + if (index != 0) + return E_FAIL; + if(!testMode && (!realOutStream)) + continue; + if (!testMode) + { + UInt32 size = m_Database.NewFormatString.Length(); + RINOK(WriteStream(realOutStream, (const char *)m_Database.NewFormatString, size, 0)); + } + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + const CItem &item = m_Database.Items[index]; + + currentItemSize = item.Size; + + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (item.Section != 0) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + if (testMode) + { + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + + RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); + streamSpec->Init(m_Stream, item.Size); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, ¤tTotalSize, ¤tTotalSize); + + if(!copyCoder) + copyCoder = new NCompress::CCopyCoder; + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + } + return S_OK; + } + + UInt64 lastFolderIndex = ((UInt64)0 - 1); + for(i = 0; i < numItems; i++) + { + UInt32 index = allFilesMode ? i : indices[i]; + int entryIndex = m_Database.Indices[index]; + const CItem &item = m_Database.Items[entryIndex]; + UInt64 sectionIndex = item.Section; + if (item.IsDirectory() || item.Size == 0) + continue; + if (sectionIndex == 0) + { + currentTotalSize += item.Size; + continue; + } + const CSectionInfo §ion = m_Database.Sections[(size_t)item.Section]; + if (section.IsLzx()) + { + const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; + UInt64 folderIndex = m_Database.GetFolder(index); + if (lastFolderIndex == folderIndex) + folderIndex++; + lastFolderIndex = m_Database.GetLastFolder(index); + for (; folderIndex <= lastFolderIndex; folderIndex++) + currentTotalSize += lzxInfo.GetFolderSize(); + } + } + + RINOK(extractCallback->SetTotal(currentTotalSize)); + + NCompress::NLzx::CDecoder *lzxDecoderSpec = 0; + CMyComPtr<ICompressCoder> lzxDecoder; + CChmFolderOutStream *chmFolderOutStream = 0; + CMyComPtr<ISequentialOutStream> outStream; + + currentTotalSize = 0; + + CRecordVector<bool> extractStatuses; + for(i = 0; i < numItems;) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + UInt32 index = allFilesMode ? i : indices[i]; + i++; + int entryIndex = m_Database.Indices[index]; + const CItem &item = m_Database.Items[entryIndex]; + UInt64 sectionIndex = item.Section; + Int32 askMode= testMode ? + NArchive::NExtract::NAskMode::kTest : + NArchive::NExtract::NAskMode::kExtract; + if (item.IsDirectory()) + { + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + RINOK(extractCallback->PrepareOperation(askMode)); + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + continue; + } + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = localProgressSpec; + localProgressSpec->Init(extractCallback, false); + + CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo; + CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; + localCompressProgressSpec->Init(progress, NULL, ¤tTotalSize); + + if (item.Size == 0 || sectionIndex == 0) + { + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + if (!testMode && item.Size != 0) + { + RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); + streamSpec->Init(m_Stream, item.Size); + if(!copyCoder) + copyCoder = new NCompress::CCopyCoder; + RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, compressProgress)); + } + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK)); + currentTotalSize += item.Size; + continue; + } + + const CSectionInfo §ion = m_Database.Sections[(size_t)sectionIndex]; + + if (!section.IsLzx()) + { + CMyComPtr<ISequentialOutStream> realOutStream; + RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); + if(!testMode && (!realOutStream)) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kUnSupportedMethod)); + continue; + } + + const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo; + + if (chmFolderOutStream == 0) + { + chmFolderOutStream = new CChmFolderOutStream; + outStream = chmFolderOutStream; + } + + chmFolderOutStream->Init(&m_Database, extractCallback, testMode); + + if(lzxDecoderSpec == NULL) + { + lzxDecoderSpec = new NCompress::NLzx::CDecoder; + lzxDecoder = lzxDecoderSpec; + } + + UInt64 folderIndex = m_Database.GetFolder(index); + + UInt64 compressedPos = m_Database.ContentOffset + section.Offset; + UInt32 numDictBits = lzxInfo.GetNumDictBits(); + RINOK(lzxDecoderSpec->SetParams(numDictBits)); + + const CItem *lastItem = &item; + extractStatuses.Clear(); + extractStatuses.Add(true); + + for (;true; folderIndex++) + { + RINOK(extractCallback->SetCompleted(¤tTotalSize)); + + UInt64 startPos = lzxInfo.GetFolderPos(folderIndex); + UInt64 finishPos = lastItem->Offset + lastItem->Size; + UInt64 limitFolderIndex = lzxInfo.GetFolder(finishPos); + + lastFolderIndex = m_Database.GetLastFolder(index); + UInt64 folderSize = lzxInfo.GetFolderSize(); + UInt64 unPackSize = folderSize; + if (extractStatuses.IsEmpty()) + chmFolderOutStream->m_StartIndex = index + 1; + else + chmFolderOutStream->m_StartIndex = index; + if (limitFolderIndex == folderIndex) + { + for(; i < numItems; i++) + { + UInt32 nextIndex = allFilesMode ? i : indices[i]; + int entryIndex = m_Database.Indices[nextIndex]; + const CItem &nextItem = m_Database.Items[entryIndex]; + if (nextItem.Section != sectionIndex) + break; + UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex); + if (nextFolderIndex != folderIndex) + break; + for (index++; index < nextIndex; index++) + extractStatuses.Add(false); + extractStatuses.Add(true); + index = nextIndex; + lastItem = &nextItem; + if (nextItem.Size != 0) + finishPos = nextItem.Offset + nextItem.Size; + lastFolderIndex = m_Database.GetLastFolder(index); + } + } + unPackSize = MyMin(finishPos - startPos, unPackSize); + + chmFolderOutStream->m_FolderSize = folderSize; + chmFolderOutStream->m_PosInFolder = 0; + chmFolderOutStream->m_PosInSection = startPos; + chmFolderOutStream->m_ExtractStatuses = &extractStatuses; + chmFolderOutStream->m_NumFiles = extractStatuses.Size(); + chmFolderOutStream->m_CurrentIndex = 0; + try + { + UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex); + const CResetTable &rt = lzxInfo.ResetTable; + UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize); + for (UInt32 b = 0; b < numBlocks; b++) + { + UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos; + RINOK(extractCallback->SetCompleted(&completedSize)); + UInt64 bCur = startBlock + b; + if (bCur >= rt.ResetOffsets.Size()) + return E_FAIL; + UInt64 startOffset = rt.ResetOffsets[(int)startBlock]; + UInt64 offset = rt.ResetOffsets[(int)bCur]; + UInt64 compressedSize; + rt.GetCompressedSizeOfBlock(bCur, compressedSize); + UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection; + if (rem > rt.BlockSize) + rem = rt.BlockSize; + const UInt64 *offsets = (const UInt64 *)&rt.ResetOffsets.Front(); + RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL)); + streamSpec->Init(m_Stream, compressedSize); + lzxDecoderSpec->SetKeepHistory(b > 0, (int)((offset - startOffset) & 1)); + RINOK(lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL)); + } + } + catch(...) + { + RINOK(chmFolderOutStream->FlushCorrupted()); + } + currentTotalSize += folderSize; + if (folderIndex == lastFolderIndex) + break; + extractStatuses.Clear(); + } + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + COM_TRY_BEGIN + *numItems = m_Database.NewFormat ? 1: + (m_Database.LowLevel ? + m_Database.Items.Size(): + m_Database.Indices.Size()); + return S_OK; + COM_TRY_END +} + +}} diff --git a/7zip/Archive/Chm/ChmHandler.h b/7zip/Archive/Chm/ChmHandler.h new file mode 100755 index 00000000..54f01b84 --- /dev/null +++ b/7zip/Archive/Chm/ChmHandler.h @@ -0,0 +1,46 @@ +// ChmHandler.h + +#ifndef __ARCHIVE_CHM_HANDLER_H +#define __ARCHIVE_CHM_HANDLER_H + +#include "Common/MyCom.h" +#include "../IArchive.h" +#include "ChmIn.h" + +namespace NArchive { +namespace NChm { + +class CHandler: + public IInArchive, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + STDMETHOD(Open)(IInStream *stream, + const UInt64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + STDMETHOD(Close)(); + STDMETHOD(GetNumberOfItems)(UInt32 *numItems); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback); + + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties); + STDMETHOD(GetPropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + +private: + CFilesDatabase m_Database; + CMyComPtr<IInStream> m_Stream; +}; + +}} + +#endif
\ No newline at end of file diff --git a/7zip/Archive/Chm/ChmHeader.cpp b/7zip/Archive/Chm/ChmHeader.cpp new file mode 100755 index 00000000..4d485b6c --- /dev/null +++ b/7zip/Archive/Chm/ChmHeader.cpp @@ -0,0 +1,24 @@ +// Archive/Chm/Header.h + +#include "StdAfx.h" + +#include "ChmHeader.h" + +namespace NArchive{ +namespace NChm{ +namespace NHeader{ + +UInt32 kItsfSignature = 0x46535449 + 1; +UInt32 kItolSignature = 0x4C4F5449 + 1; +static class CSignatureInitializer +{ +public: + CSignatureInitializer() + { + kItsfSignature--; + kItolSignature--; + } +}g_SignatureInitializer; + + +}}} diff --git a/7zip/Archive/Chm/ChmHeader.h b/7zip/Archive/Chm/ChmHeader.h new file mode 100755 index 00000000..9f1bd42b --- /dev/null +++ b/7zip/Archive/Chm/ChmHeader.h @@ -0,0 +1,28 @@ +// Archive/Chm/Header.h + +#ifndef __ARCHIVE_CHM_HEADER_H +#define __ARCHIVE_CHM_HEADER_H + +#include "Common/Types.h" + +namespace NArchive { +namespace NChm { +namespace NHeader{ + +const UInt32 kItspSignature = 0x50535449; +const UInt32 kPmglSignature = 0x4C474D50; +const UInt32 kLzxcSignature = 0x43585A4C; + +const UInt32 kIfcmSignature = 0x4D434649; +const UInt32 kAollSignature = 0x4C4C4F41; +const UInt32 kCaolSignature = 0x4C4F4143; + +extern UInt32 kItsfSignature; + +extern UInt32 kItolSignature; +const UInt32 kItlsSignature = 0x534C5449; +UInt64 inline GetHxsSignature() { return ((UInt64)kItlsSignature << 32) | kItolSignature; } + +}}} + +#endif diff --git a/7zip/Archive/Chm/ChmIn.cpp b/7zip/Archive/Chm/ChmIn.cpp new file mode 100755 index 00000000..79e934ad --- /dev/null +++ b/7zip/Archive/Chm/ChmIn.cpp @@ -0,0 +1,924 @@ +// Archive/ChmIn.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" +#include "Common/UTFConvert.h" +#include "Common/IntToString.h" +#include "Windows/Defs.h" + +#include "../../Common/LimitedStreams.h" +#include "ChmIn.h" + +namespace NArchive{ +namespace NChm{ + +// define CHM_LOW, if you want to see low level items +// #define CHM_LOW + +static const GUID kChmLzxGuid = + { 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C }; +static const GUID kHelp2LzxGuid = + { 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 }; +static const GUID kDesGuid = + { 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF }; + +static bool AreGuidsEqual(REFGUID g1, REFGUID g2) +{ + if (g1.Data1 != g2.Data1 || + g1.Data2 != g2.Data2 || + g1.Data3 != g2.Data3) + return false; + for (int i = 0; i < 8; i++) + if (g1.Data4[i] != g2.Data4[i]) + return false; + return true; +} + +static char GetHex(Byte value) +{ + return (value < 10) ? ('0' + value) : ('A' + (value - 10)); +} + +static void PrintByte(Byte b, AString &s) +{ + s += GetHex(b >> 4); + s += GetHex(b & 0xF); +} + +static void PrintUInt16(UInt16 v, AString &s) +{ + PrintByte((Byte)(v >> 8), s); + PrintByte((Byte)v, s); +} + +static void PrintUInt32(UInt32 v, AString &s) +{ + PrintUInt16((UInt16)(v >> 16), s); + PrintUInt16((UInt16)v, s); +} + +AString CMethodInfo::GetGuidString() const +{ + AString s; + s += '{'; + PrintUInt32(Guid.Data1, s); + s += '-'; + PrintUInt16(Guid.Data2, s); + s += '-'; + PrintUInt16(Guid.Data3, s); + s += '-'; + PrintByte(Guid.Data4[0], s); + PrintByte(Guid.Data4[1], s); + s += '-'; + for (int i = 2; i < 8; i++) + PrintByte(Guid.Data4[i], s); + s += '}'; + return s; +} + +bool CMethodInfo::IsLzx() const +{ + if (AreGuidsEqual(Guid, kChmLzxGuid)) + return true; + return AreGuidsEqual(Guid, kHelp2LzxGuid); +} + +bool CMethodInfo::IsDes() const +{ + return AreGuidsEqual(Guid, kDesGuid); +} + +UString CMethodInfo::GetName() const +{ + UString s; + if (IsLzx()) + { + s = L"LZX:"; + UInt32 numDictBits = LzxInfo.GetNumDictBits(); + wchar_t temp[32]; + ConvertUInt64ToString(numDictBits, temp); + s += temp; + } + else + { + AString s2; + if (IsDes()) + s2 = "DES"; + else + { + s2 = GetGuidString(); + if (ControlData.GetCapacity() > 0) + { + s2 += ":"; + for (size_t i = 0; i < ControlData.GetCapacity(); i++) + PrintByte(ControlData[i], s2); + } + } + ConvertUTF8ToUnicode(s2, s); + } + return s; +} + +bool CSectionInfo::IsLzx() const +{ + if (Methods.Size() != 1) + return false; + return Methods[0].IsLzx(); +} + +UString CSectionInfo::GetMethodName() const +{ + UString s; + if (!IsLzx()) + { + UString temp; + if (ConvertUTF8ToUnicode(Name, temp)) + s += temp; + s += L": "; + } + for (int i = 0; i < Methods.Size(); i++) + { + if (i != 0) + s += L" "; + s += Methods[i].GetName(); + } + return s; +} + +Byte CInArchive::ReadByte() +{ + Byte b; + if (!_inBuffer.ReadByte(b)) + throw 1; + return b; +} + +void CInArchive::Skeep(size_t size) +{ + while (size-- != 0) + ReadByte(); +} + +void CInArchive::ReadBytes(Byte *data, UInt32 size) +{ + for (UInt32 i = 0; i < size; i++) + data[i] = ReadByte(); +} + +UInt16 CInArchive::ReadUInt16() +{ + UInt16 value = 0; + for (int i = 0; i < 2; i++) + value |= ((UInt16)(ReadByte()) << (8 * i)); + return value; +} + +UInt32 CInArchive::ReadUInt32() +{ + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= ((UInt32)(ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadUInt64() +{ + UInt64 value = 0; + for (int i = 0; i < 8; i++) + value |= ((UInt64)(ReadByte()) << (8 * i)); + return value; +} + +UInt64 CInArchive::ReadEncInt() +{ + UInt64 val = 0;; + for (int i = 0; i < 10; i++) + { + Byte b = ReadByte(); + val |= (b & 0x7F); + if (b < 0x80) + return val; + val <<= 7; + } + throw 1; +} + +void CInArchive::ReadGUID(GUID &g) +{ + g.Data1 = ReadUInt32(); + g.Data2 = ReadUInt16(); + g.Data3 = ReadUInt16(); + ReadBytes(g.Data4, 8); +} + +void CInArchive::ReadString(int size, AString &s) +{ + s.Empty(); + while(size-- != 0) + { + char c = (char)ReadByte(); + if (c == 0) + { + Skeep(size); + return; + } + s += c; + } +} + +void CInArchive::ReadUString(int size, UString &s) +{ + s.Empty(); + while(size-- != 0) + { + wchar_t c = ReadUInt16(); + if (c == 0) + { + Skeep(2 * size); + return; + } + s += c; + } +} + +HRESULT CInArchive::ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size) +{ + RINOK(inStream->Seek(pos, STREAM_SEEK_SET, NULL)); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; + CMyComPtr<ISequentialInStream> limitedStream(streamSpec); + streamSpec->Init(inStream, size); + _inBuffer.SetStream(limitedStream); + _inBuffer.Init(); + return S_OK; +} + +HRESULT CInArchive::ReadDirEntry(CDatabase &database) +{ + CItem item; + UInt64 nameLength = ReadEncInt(); + if (nameLength == 0 || nameLength >= 0x10000000) + return S_FALSE; + ReadString((int)nameLength, item.Name); + item.Section = ReadEncInt(); + item.Offset = ReadEncInt(); + item.Size = ReadEncInt(); + database.Items.Add(item); + return S_OK; +} + +HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database) +{ + UInt32 headerSize = ReadUInt32(); + if (headerSize != 0x60) + return S_FALSE; + UInt32 unknown1 = ReadUInt32(); + if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file + return S_FALSE; + UInt32 timeStamp = ReadUInt32(); + // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and + // fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional bits. + // The 4 least significant bits in the last byte are constant. + UInt32 lang = ReadUInt32(); + GUID g; + ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC} + ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC} + const int kNumSections = 2; + UInt64 sectionOffsets[kNumSections]; + UInt64 sectionSizes[kNumSections]; + int i; + for (i = 0; i < kNumSections; i++) + { + sectionOffsets[i] = ReadUInt64(); + sectionSizes[i] = ReadUInt64(); + } + // if (chmVersion == 3) + database.ContentOffset = ReadUInt64(); + /* + else + database.ContentOffset = _startPosition + 0x58 + */ + + /* + // Section 0 + ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]); + if (sectionSizes[0] != 0x18) + return S_FALSE; + ReadUInt32(); // unknown: 01FE + ReadUInt32(); // unknown: 0 + UInt64 fileSize = ReadUInt64(); + ReadUInt32(); // unknown: 0 + ReadUInt32(); // unknown: 0 + */ + + // Section 1: The Directory Listing + ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]); + if (ReadUInt32() != NHeader::kItspSignature) + return S_FALSE; + if (ReadUInt32() != 1) // version + return S_FALSE; + UInt32 dirHeaderSize = ReadUInt32(); + ReadUInt32(); // 0x0A (unknown) + UInt32 dirChunkSize = ReadUInt32(); // $1000 + if (dirChunkSize < 32) + return S_FALSE; + UInt32 density = ReadUInt32(); // "Density" of quickref section, usually 2. + UInt32 depth = ReadUInt32(); // Depth of the index tree: 1 there is no index, + // 2 if there is one level of PMGI chunks. + + UInt32 chunkNumber = ReadUInt32(); // Chunk number of root index chunk, -1 if there is none + // (though at least one file has 0 despite there being no + // index chunk, probably a bug.) + UInt32 firstPmglChunkNumber = ReadUInt32(); // Chunk number of first PMGL (listing) chunk + UInt32 lastPmglChunkNumber = ReadUInt32(); // Chunk number of last PMGL (listing) chunk + ReadUInt32(); // -1 (unknown) + UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total) + UInt32 windowsLangId = ReadUInt32(); + ReadGUID(g); // {5D02926A-212E-11D0-9DF9-00A0C922E6EC} + ReadUInt32(); // 0x54 (This is the length again) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + + for (UInt32 ci = 0; ci < numDirChunks; ci++) + { + UInt64 chunkPos = _inBuffer.GetProcessedSize(); + if (ReadUInt32() == NHeader::kPmglSignature) + { + // The quickref area is written backwards from the end of the chunk. + // One quickref entry exists for every n entries in the file, where n + // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5. + + UInt32 quickrefLength = ReadUInt32(); // Length of free space and/or quickref area at end of directory chunk + if (quickrefLength > dirChunkSize || quickrefLength < 2) + return S_FALSE; + ReadUInt32(); // Always 0 + ReadUInt32(); // Chunk number of previous listing chunk when reading + // directory in sequence (-1 if this is the first listing chunk) + ReadUInt32(); // Chunk number of next listing chunk when reading + // directory in sequence (-1 if this is the last listing chunk) + int numItems = 0; + while (true) + { + UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + UInt32 offsetLimit = dirChunkSize - quickrefLength; + if (offset > offsetLimit) + return S_FALSE; + if (offset == offsetLimit) + break; + RINOK(ReadDirEntry(database)); + numItems++; + } + Skeep(quickrefLength - 2); + if (ReadUInt16() != numItems) + return S_FALSE; + } + else + Skeep(dirChunkSize - 4); + } + return S_OK; +} + +HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database) +{ + if (ReadUInt32() != 1) // version + return S_FALSE; + if (ReadUInt32() != 0x28) // Location of header section table + return S_FALSE; + UInt32 numHeaderSections = ReadUInt32(); + const int kNumHeaderSectionsMax = 5; + if (numHeaderSections != kNumHeaderSectionsMax) + return S_FALSE; + ReadUInt32(); // Length of post-header table + GUID g; + ReadGUID(g); // {0A9007C1-4076-11D3-8789-0000F8105754} + + // header section table + UInt64 sectionOffsets[kNumHeaderSectionsMax]; + UInt64 sectionSizes[kNumHeaderSectionsMax]; + UInt32 i; + for (i = 0; i < numHeaderSections; i++) + { + sectionOffsets[i] = ReadUInt64(); + sectionSizes[i] = ReadUInt64(); + } + + // Post-Header + ReadUInt32(); // 2 + ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header) + // ----- Directory information + ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1 + ReadUInt64(); // Chunk number of first AOLL chunk in directory + ReadUInt64(); // Chunk number of last AOLL chunk in directory + ReadUInt64(); // 0 (unknown) + ReadUInt32(); // $2000 (Directory chunk size of directory) + ReadUInt32(); // Quickref density for main directory, usually 2 + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // Depth of main directory index tree + // 1 there is no index, 2 if there is one level of AOLI chunks. + ReadUInt64(); // 0 (unknown) + UInt64 numDirEntries = ReadUInt64(); // Number of directory entries + // ----- Directory Index Information + ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index) + ReadUInt64(); // Chunk number of first AOLL chunk in directory index + ReadUInt64(); // Chunk number of last AOLL chunk in directory index + ReadUInt64(); // 0 (unknown) + ReadUInt32(); // $200 (Directory chunk size of directory index) + ReadUInt32(); // Quickref density for directory index, usually 2 + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // Depth of directory index index tree. + ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0. + ReadUInt64(); // Number of directory index entries (same as number of AOLL + // chunks in main directory) + + // (The obvious guess for the following two fields, which recur in a number + // of places, is they are maximum sizes for the directory and directory index. + // However, I have seen no direct evidence that this is the case.) + + ReadUInt32(); // $100000 (Same as field following chunk size in directory) + ReadUInt32(); // $20000 (Same as field following chunk size in directory index) + + ReadUInt64(); // 0 (unknown) + if (ReadUInt32() != NHeader::kCaolSignature) + return S_FALSE; + if (ReadUInt32() != 2) // (Most likely a version number) + return S_FALSE; + UInt32 caolLength = ReadUInt32(); // $50 (Length of the CAOL section, which includes the ITSF section) + if (caolLength >= 0x2C) + { + UInt32 c7 = ReadUInt16(); // Unknown. Remains the same when identical files are built. + // Does not appear to be a checksum. Many files have + // 'HH' (HTML Help?) here, indicating this may be a compiler ID + // field. But at least one ITOL/ITLS compiler does not set this + // field to a constant value. + ReadUInt16(); // 0 (Unknown. Possibly part of 00A4 field) + ReadUInt32(); // Unknown. Two values have been seen -- $43ED, and 0. + ReadUInt32(); // $2000 (Directory chunk size of directory) + ReadUInt32(); // $200 (Directory chunk size of directory index) + ReadUInt32(); // $100000 (Same as field following chunk size in directory) + ReadUInt32(); // $20000 (Same as field following chunk size in directory index) + ReadUInt32(); // 0 (unknown) + ReadUInt32(); // 0 (Unknown) + if (caolLength == 0x2C) + { + database.ContentOffset = 0; + database.NewFormat = true; + } + else if (caolLength == 0x50) + { + ReadUInt32(); // 0 (Unknown) + if (ReadUInt32() != NHeader::kItsfSignature) + return S_FALSE; + if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3) + return S_FALSE; + if (ReadUInt32() != 0x20) // $20 (length of ITSF) + return S_FALSE; + UInt32 unknown = ReadUInt32(); + if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases; + return S_FALSE; + database.ContentOffset = _startPosition + ReadUInt64(); + UInt32 timeStamp = ReadUInt32(); + // A timestamp of some sort. + // Considered as a big-endian DWORD, it appears to contain + // seconds (MSB) and fractional seconds (second byte). + // The third and fourth bytes may contain even more fractional + // bits. The 4 least significant bits in the last byte are constant. + UInt32 lang = ReadUInt32(); // BE? + } + else + return S_FALSE; + } + + /* + // Section 0 + ReadChunk(inStream, _startPosition + sectionOffsets[0], sectionSizes[0]); + if (sectionSizes[0] != 0x18) + return S_FALSE; + ReadUInt32(); // unknown: 01FE + ReadUInt32(); // unknown: 0 + UInt64 fileSize = ReadUInt64(); + ReadUInt32(); // unknown: 0 + ReadUInt32(); // unknown: 0 + */ + + // Section 1: The Directory Listing + ReadChunk(inStream, _startPosition + sectionOffsets[1], sectionSizes[1]); + if (ReadUInt32() != NHeader::kIfcmSignature) + return S_FALSE; + if (ReadUInt32() != 1) // (probably a version number) + return S_FALSE; + UInt32 dirChunkSize = ReadUInt32(); // $2000 + if (dirChunkSize < 64) + return S_FALSE; + ReadUInt32(); // $100000 (unknown) + ReadUInt32(); // -1 (unknown) + ReadUInt32(); // -1 (unknown) + UInt32 numDirChunks = ReadUInt32(); + ReadUInt32(); // 0 (unknown, probably high word of above) + + for (UInt32 ci = 0; ci < numDirChunks; ci++) + { + UInt64 chunkPos = _inBuffer.GetProcessedSize(); + if (ReadUInt32() == NHeader::kAollSignature) + { + UInt32 quickrefLength = ReadUInt32(); // Length of quickref area at end of directory chunk + if (quickrefLength > dirChunkSize || quickrefLength < 2) + return S_FALSE; + ReadUInt64(); // Directory chunk number + // This must match physical position in file, that is + // the chunk size times the chunk number must be the + // offset from the end of the directory header. + ReadUInt64(); // Chunk number of previous listing chunk when reading + // directory in sequence (-1 if first listing chunk) + ReadUInt64(); // Chunk number of next listing chunk when reading + // directory in sequence (-1 if last listing chunk) + ReadUInt64(); // Number of first listing entry in this chunk + ReadUInt32(); // 1 (unknown -- other values have also been seen here) + ReadUInt32(); // 0 (unknown) + + int numItems = 0; + while (true) + { + UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; + UInt32 offsetLimit = dirChunkSize - quickrefLength; + if (offset > offsetLimit) + return S_FALSE; + if (offset == offsetLimit) + break; + if (database.NewFormat) + { + UInt16 nameLength = ReadUInt16(); + if (nameLength == 0) + return S_FALSE; + UString name; + ReadUString((int)nameLength, name); + AString s; + ConvertUnicodeToUTF8(name, s); + Byte b = ReadByte(); + s += ' '; + PrintByte(b, s); + s += ' '; + UInt64 len = ReadEncInt(); + // then number of items ? + // then length ? + // then some data (binary encoding?) + while (len-- != 0) + { + b = ReadByte(); + PrintByte(b, s); + } + database.NewFormatString += s; + database.NewFormatString += "\r\n"; + } + else + { + RINOK(ReadDirEntry(database)); + } + numItems++; + } + Skeep(quickrefLength - 2); + if (ReadUInt16() != numItems) + return S_FALSE; + if (numItems > numDirEntries) + return S_FALSE; + numDirEntries -= numItems; + } + else + Skeep(dirChunkSize - 4); + } + return numDirEntries == 0 ? S_OK : S_FALSE; +} + +HRESULT CInArchive::DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name) +{ + int index = database.FindItem(name); + if (index < 0) + return S_FALSE; + const CItem &item = database.Items[index]; + _chunkSize = item.Size; + return ReadChunk(inStream, database.ContentOffset + item.Offset, item.Size); +} + + +#define DATA_SPACE "::DataSpace/" +static const char *kNameList = DATA_SPACE "NameList"; +static const char *kStorage = DATA_SPACE "Storage/"; +static const char *kContent = "Content"; +static const char *kControlData = "ControlData"; +static const char *kSpanInfo = "SpanInfo"; +static const char *kTransform = "Transform/"; +static const char *kResetTable = "/InstanceData/ResetTable"; +static const char *kTransformList = "List"; + +static AString GetSectionPrefix(const AString &name) +{ + return AString(kStorage) + name + AString("/"); +} + +#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; } + +static int CompareFiles(const int *p1, const int *p2, void *param) +{ + const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param; + const CItem &item1 = items[*p1]; + const CItem &item2 = items[*p2]; + bool isDir1 = item1.IsDirectory(); + bool isDir2 = item2.IsDirectory(); + if (isDir1 && !isDir2) + return -1; + if (isDir2) + { + if (isDir1) + return MyCompare(*p1, *p2); + return 1; + } + RINOZ(MyCompare(item1.Section, item2.Section)); + RINOZ(MyCompare(item1.Offset, item2.Offset)); + RINOZ(MyCompare(item1.Size, item2.Size)); + return MyCompare(*p1, *p2); +} + +void CFilesDatabase::SetIndices() +{ + for (int i = 0; i < Items.Size(); i++) + { + const CItem &item = Items[i]; + if (item.IsUserItem() && item.Name.Length() != 1) + Indices.Add(i); + } +} + +void CFilesDatabase::Sort() +{ + Indices.Sort(CompareFiles, (void *)&Items); +} + +bool CFilesDatabase::Check() +{ + UInt64 maxPos = 0; + UInt64 prevSection = 0; + for(int i = 0; i < Indices.Size(); i++) + { + const CItem &item = Items[Indices[i]]; + if (item.Section == 0 || item.IsDirectory()) + continue; + if (item.Section != prevSection) + { + prevSection = item.Section; + maxPos = 0; + continue; + } + if (item.Offset < maxPos) + return false; + maxPos = item.Offset + item.Size; + if (maxPos < item.Offset) + return false; + } + return true; +} + +HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database) +{ + { + // The NameList file + RINOK(DecompressStream(inStream, database, kNameList)); + UInt16 length = ReadUInt16(); + UInt16 numSections = ReadUInt16(); + for (int i = 0; i < numSections; i++) + { + CSectionInfo section; + UInt16 nameLength = ReadUInt16(); + UString name; + ReadUString(nameLength, name); + if (ReadUInt16() != 0) + return S_FALSE; + if (!ConvertUnicodeToUTF8(name, section.Name)) + return S_FALSE; + database.Sections.Add(section); + } + } + + int i; + for (i = 1; i < database.Sections.Size(); i++) + { + CSectionInfo §ion = database.Sections[i]; + AString sectionPrefix = GetSectionPrefix(section.Name); + { + // Content + int index = database.FindItem(sectionPrefix + kContent); + if (index < 0) + return S_FALSE; + const CItem &item = database.Items[index]; + section.Offset = item.Offset; + section.CompressedSize = item.Size; + } + AString transformPrefix = sectionPrefix + kTransform; + if (database.Help2Format) + { + // Transform List + RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList)); + if ((_chunkSize & 0xF) != 0) + return S_FALSE; + int numGuids = (int)(_chunkSize / 0x10); + if (numGuids < 1) + return S_FALSE; + for (int i = 0; i < numGuids; i++) + { + CMethodInfo method; + ReadGUID(method.Guid); + section.Methods.Add(method); + } + } + else + { + CMethodInfo method; + method.Guid = kChmLzxGuid; + section.Methods.Add(method); + } + + { + // Control Data + RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData)); + for (int mi = 0; mi < section.Methods.Size(); mi++) + { + CMethodInfo &method = section.Methods[mi]; + UInt32 numDWORDS = ReadUInt32(); + if (method.IsLzx()) + { + if (numDWORDS < 5) + return S_FALSE; + if (ReadUInt32() != NHeader::kLzxcSignature) + return S_FALSE; + CLzxInfo &li = method.LzxInfo; + li.Version = ReadUInt32(); + if (li.Version != 2 && li.Version != 3) + return S_FALSE; + li.ResetInterval = ReadUInt32(); + li.WindowSize = ReadUInt32(); + li.CacheSize = ReadUInt32(); + if (li.ResetInterval != 2 && li.ResetInterval != 4) + return S_FALSE; + if (li.WindowSize != 2 && li.WindowSize != 4) + return S_FALSE; + numDWORDS -= 5; + while (numDWORDS-- != 0) + ReadUInt32(); + } + else + { + UInt32 numBytes = numDWORDS * 4; + method.ControlData.SetCapacity(numBytes); + ReadBytes(method.ControlData, numBytes); + } + } + } + + { + // SpanInfo + RINOK(DecompressStream(inStream, database, sectionPrefix + kSpanInfo)); + section.UncompressedSize = ReadUInt64(); + } + + // read ResetTable for LZX + for (int mi = 0; mi < section.Methods.Size(); mi++) + { + CMethodInfo &method = section.Methods[mi]; + if (method.IsLzx()) + { + // ResetTable; + RINOK(DecompressStream(inStream, database, transformPrefix + + method.GetGuidString() + kResetTable)); + CResetTable &rt = method.LzxInfo.ResetTable; + if (_chunkSize < 4) + { + if (_chunkSize != 0) + return S_FALSE; + // ResetTable is empty in .chw files + if (section.UncompressedSize != 0) + return S_FALSE; + rt.UncompressedSize = 0; + rt.CompressedSize = 0; + rt.BlockSize = 0; + } + else + { + UInt32 ver = ReadUInt32(); // 2 unknown (possibly a version number) + if (ver != 2 && ver != 3) + return S_FALSE; + UInt32 numEntries = ReadUInt32(); + if (ReadUInt32() != 8) // Size of table entry (bytes) + return S_FALSE; + if (ReadUInt32() != 0x28) // Length of table header + return S_FALSE; + rt.UncompressedSize = ReadUInt64(); + rt.CompressedSize = ReadUInt64(); + rt.BlockSize = ReadUInt64(); // 0x8000 block size for locations below + if (rt.BlockSize != 0x8000) + return S_FALSE; + rt.ResetOffsets.Reserve(numEntries); + for (UInt32 i = 0; i < numEntries; i++) + rt.ResetOffsets.Add(ReadUInt64()); + } + } + } + } + + database.SetIndices(); + database.Sort(); + return database.Check() ? S_OK : S_FALSE; +} + +HRESULT CInArchive::Open2(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CFilesDatabase &database) +{ + database.Clear(); + + RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &_startPosition)); + + database.Help2Format = false; + const UInt32 chmVersion = 3; + { + if (!_inBuffer.Create(1 << 14)) + return E_OUTOFMEMORY; + _inBuffer.SetStream(inStream); + _inBuffer.Init(); + UInt64 value = 0; + const int kSignatureSize = 8; + UInt64 hxsSignature = NHeader::GetHxsSignature(); + UInt64 chmSignature = ((UInt64)chmVersion << 32)| NHeader::kItsfSignature; + while(true) + { + Byte b; + if (!_inBuffer.ReadByte(b)) + return S_FALSE; + value >>= 8; + value |= ((UInt64)b) << ((kSignatureSize - 1) * 8); + if (_inBuffer.GetProcessedSize() >= kSignatureSize) + { + if (value == chmSignature) + break; + if (value == hxsSignature) + { + database.Help2Format = true; + break; + } + if (searchHeaderSizeLimit != NULL) + if (_inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit)) + return S_FALSE; + } + } + _startPosition += _inBuffer.GetProcessedSize() - kSignatureSize; + } + + if (database.Help2Format) + { + RINOK(OpenHelp2(inStream, database)); + if (database.NewFormat) + return S_OK; + } + else + { + RINOK(OpenChm(inStream, database)); + } + + #ifndef CHM_LOW + try + { + HRESULT res = OpenHighLevel(inStream, database); + if (res == S_FALSE) + { + database.HighLevelClear(); + return S_OK; + } + RINOK(res); + database.LowLevel = false; + } + catch(...) + { + return S_OK; + } + #endif + return S_OK; +} + +HRESULT CInArchive::Open(IInStream *inStream, + const UInt64 *searchHeaderSizeLimit, + CFilesDatabase &database) +{ + try + { + HRESULT res = Open2(inStream, searchHeaderSizeLimit, database); + _inBuffer.ReleaseStream(); + return res; + } + catch(...) + { + _inBuffer.ReleaseStream(); + throw; + } +} + +}} diff --git a/7zip/Archive/Chm/ChmIn.h b/7zip/Archive/Chm/ChmIn.h new file mode 100755 index 00000000..d2ddb378 --- /dev/null +++ b/7zip/Archive/Chm/ChmIn.h @@ -0,0 +1,242 @@ +// Archive/ChmIn.h + +#ifndef __ARCHIVE_CHM_IN_H +#define __ARCHIVE_CHM_IN_H + +#include "Common/String.h" +#include "Common/Buffer.h" +#include "../../IStream.h" +#include "../../Common/InBuffer.h" +#include "ChmHeader.h" + +namespace NArchive { +namespace NChm { + +struct CItem +{ + UInt64 Section; + UInt64 Offset; + UInt64 Size; + AString Name; + + bool IsFormatRelatedItem() const + { + if (Name.Length() < 2) + return false; + return Name[0] == ':' && Name[1] == ':'; + } + + bool IsUserItem() const + { + if (Name.Length() < 2) + return false; + return Name[0] == '/'; + } + + bool IsDirectory() const + { + if (Name.Length() == 0) + return false; + return (Name[Name.Length() - 1] == '/'); + } +}; + +struct CDatabase +{ + UInt64 ContentOffset; + CObjectVector<CItem> Items; + AString NewFormatString; + bool Help2Format; + bool NewFormat; + + int FindItem(const AString &name) const + { + for (int i = 0; i < Items.Size(); i++) + if (Items[i].Name == name) + return i; + return -1; + } + + void Clear() + { + NewFormat = false; + NewFormatString.Empty(); + Help2Format = false; + Items.Clear(); + } +}; + +struct CResetTable +{ + UInt64 UncompressedSize; + UInt64 CompressedSize; + UInt64 BlockSize; + CRecordVector<UInt64> ResetOffsets; + bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const + { + if (blockIndex >= ResetOffsets.Size()) + return false; + UInt64 startPos = ResetOffsets[(size_t)blockIndex]; + if (blockIndex + numBlocks >= ResetOffsets.Size()) + size = CompressedSize - startPos; + else + size = ResetOffsets[(size_t)blockIndex + numBlocks] - startPos; + return true; + } + bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const + { + return GetCompressedSizeOfBlocks(blockIndex, 1, size); + } + UInt64 GetNumBlocks(UInt64 size) const + { + return (size + BlockSize - 1) / BlockSize; + } +}; + +struct CLzxInfo +{ + UInt32 Version; + UInt32 ResetInterval; + UInt32 WindowSize; + UInt32 CacheSize; + CResetTable ResetTable; + + UInt32 GetNumDictBits() const + { + if (Version == 2 || Version == 3) + { + for (int i = 0; i <= 31; i++) + if (((UInt32)1 << i) >= WindowSize) + return 15 + i; + } + return 0; + } + + UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; }; + UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }; + UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }; + UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; }; + bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const + { + UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + if (blockIndex >= ResetTable.ResetOffsets.Size()) + return false; + offset = ResetTable.ResetOffsets[(size_t)blockIndex]; + return true; + } + bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const + { + UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex); + return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size); + } +}; + +struct CMethodInfo +{ + GUID Guid; + CByteBuffer ControlData; + CLzxInfo LzxInfo; + bool IsLzx() const; + bool IsDes() const; + AString GetGuidString() const; + UString GetName() const; +}; + +struct CSectionInfo +{ + UInt64 Offset; + UInt64 CompressedSize; + UInt64 UncompressedSize; + + AString Name; + CObjectVector<CMethodInfo> Methods; + + bool IsLzx() const; + UString GetMethodName() const; +}; + +class CFilesDatabase: public CDatabase +{ +public: + bool LowLevel; + CRecordVector<int> Indices; + CObjectVector<CSectionInfo> Sections; + + UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; } + UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; } + + UInt64 GetFolder(int fileIndex) const + { + const CItem &item = Items[Indices[fileIndex]]; + const CSectionInfo §ion = Sections[(size_t)item.Section]; + if (section.IsLzx()) + return section.Methods[0].LzxInfo.GetFolder(item.Offset); + return 0; + } + + UInt64 GetLastFolder(int fileIndex) const + { + const CItem &item = Items[Indices[fileIndex]]; + const CSectionInfo §ion = Sections[(size_t)item.Section]; + if (section.IsLzx()) + return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1); + return 0; + } + + void HighLevelClear() + { + LowLevel = true; + Indices.Clear(); + Sections.Clear(); + } + + void Clear() + { + CDatabase::Clear(); + HighLevelClear(); + } + void SetIndices(); + void Sort(); + bool Check(); +}; + +class CProgressVirt +{ +public: + STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE; + STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE; +}; + +class CInArchive +{ + UInt64 _startPosition; + ::CInBuffer _inBuffer; + UInt64 _chunkSize; + + Byte ReadByte(); + void ReadBytes(Byte *data, UInt32 size); + void Skeep(size_t size); + UInt16 ReadUInt16(); + UInt32 ReadUInt32(); + UInt64 ReadUInt64(); + UInt64 ReadEncInt(); + void ReadString(int size, AString &s); + void ReadUString(int size, UString &s); + void ReadGUID(GUID &g); + + HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size); + + HRESULT ReadDirEntry(CDatabase &database); + HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name); + +public: + HRESULT OpenChm(IInStream *inStream, CDatabase &database); + HRESULT OpenHelp2(IInStream *inStream, CDatabase &database); + HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database); + HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); + HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database); +}; + +}} + +#endif diff --git a/7zip/Archive/Chm/DllExports.cpp b/7zip/Archive/Chm/DllExports.cpp new file mode 100755 index 00000000..edc87a8c --- /dev/null +++ b/7zip/Archive/Chm/DllExports.cpp @@ -0,0 +1,77 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" +#include "ChmHandler.h" +#include "../../ICoder.h" + +// {23170F69-40C1-278A-1000-000110E90000} +DEFINE_GUID(CLSID_CChmHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xE9, 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_CChmHandler) + return CLASS_E_CLASSNOTAVAILABLE; + if (*interfaceID != IID_IInArchive) + return E_NOINTERFACE; + CMyComPtr<IInArchive> inArchive = (IInArchive *)new NArchive::NChm::CHandler; + *outObject = inArchive.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case NArchive::kName: + propVariant = L"Chm"; + break; + case NArchive::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CChmHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kExtension: + propVariant = L"chm chi chq chw hxs hxi hxr hxq hxw lit"; + break; + case NArchive::kUpdate: + propVariant = false; + break; + case NArchive::kKeepName: + propVariant = false; + break; + case NArchive::kStartSignature: + { + const char sig[] = { 'I', 'T', 'S', 'F' }; + if ((value->bstrVal = ::SysAllocStringByteLen(sig, 4)) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NArchive::kAssociate: + { + propVariant = false; + break; + } + } + propVariant.Detach(value); + return S_OK; +} diff --git a/7zip/Archive/Chm/StdAfx.cpp b/7zip/Archive/Chm/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Archive/Chm/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Archive/Chm/StdAfx.h b/7zip/Archive/Chm/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Archive/Chm/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Archive/Chm/makefile b/7zip/Archive/Chm/makefile new file mode 100755 index 00000000..4adce2f5 --- /dev/null +++ b/7zip/Archive/Chm/makefile @@ -0,0 +1,68 @@ +PROG = chm.dll +DEF_FILE = ../Archive.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib user32.lib + +CHM_OBJS = \ + $O\DllExports.obj \ + $O\ChmHandler.obj \ + $O\ChmHeader.obj \ + $O\ChmIn.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + +WIN_OBJS = \ + $O\PropVariant.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ + $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ + +AR_COMMON_OBJS = \ + $O\ItemNameUtils.obj \ + +COMPRESS_LZX_OBJS = \ + $O\LzxDecoder.obj \ + $O\Lzx86Converter.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CHM_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(AR_COMMON_OBJS) \ + $(COMPRESS_LZX_OBJS) \ + $O\LZOutWindow.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(CHM_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(AR_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(COMPRESS_LZX_OBJS): ../../Compress/Lzx/$(*B).cpp + $(COMPL_O2) +$O\LZOutWindow.obj: ../../Compress/LZ/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) + diff --git a/7zip/Archive/Chm/resource.rc b/7zip/Archive/Chm/resource.rc new file mode 100755 index 00000000..fc93ae4f --- /dev/null +++ b/7zip/Archive/Chm/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Chm Plugin", "chm") diff --git a/7zip/Archive/Common/DummyOutStream.cpp b/7zip/Archive/Common/DummyOutStream.cpp index f188ac05..b1d49913 100755 --- a/7zip/Archive/Common/DummyOutStream.cpp +++ b/7zip/Archive/Common/DummyOutStream.cpp @@ -18,13 +18,3 @@ STDMETHODIMP CDummyOutStream::Write(const void *data, *processedSize = size; return S_OK; } - -STDMETHODIMP CDummyOutStream::WritePart(const void *data, - UInt32 size, UInt32 *processedSize) -{ - if(m_Stream) - return m_Stream->WritePart(data, size, processedSize); - if(processedSize != NULL) - *processedSize = size; - return S_OK; -} diff --git a/7zip/Archive/Common/DummyOutStream.h b/7zip/Archive/Common/DummyOutStream.h index 2e66cd3d..51690787 100755 --- a/7zip/Archive/Common/DummyOutStream.h +++ b/7zip/Archive/Common/DummyOutStream.h @@ -14,7 +14,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CMyComPtr<ISequentialOutStream> m_Stream; public: diff --git a/7zip/Archive/Common/FilterCoder.cpp b/7zip/Archive/Common/FilterCoder.cpp index 3a7a95b6..1ad0f5de 100755 --- a/7zip/Archive/Common/FilterCoder.cpp +++ b/7zip/Archive/Common/FilterCoder.cpp @@ -5,6 +5,7 @@ #include "FilterCoder.h" #include "../../../Common/Alloc.h" #include "../../../Common/Defs.h" +#include "../../Common/StreamUtils.h" static const int kBufferSize = 1 << 17; @@ -27,7 +28,7 @@ HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 siz size = (UInt32)remSize; } UInt32 processedSize = 0; - RINOK(outStream->Write(_buffer, size, &processedSize)); + RINOK(WriteStream(outStream, _buffer, size, &processedSize)); if (size != processedSize) return E_FAIL; _nowPos64 += processedSize; @@ -47,8 +48,10 @@ STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream, while(NeedMore()) { UInt32 processedSize; - UInt32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); + + // Change it: It can be optimized using ReadPart + RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize)); + UInt32 endPos = bufferPos + processedSize; bufferPos = Filter->Filter(_buffer, endPos); @@ -131,11 +134,6 @@ STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processe return S_OK; } -STDMETHODIMP CFilterCoder::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - STDMETHODIMP CFilterCoder::Flush() { if (_bufferPos != 0) @@ -149,7 +147,7 @@ STDMETHODIMP CFilterCoder::Flush() return E_FAIL; } UInt32 processedSize; - RINOK(_outStream->Write(_buffer, _bufferPos, &processedSize)); + RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize)); if (_bufferPos != processedSize) return E_FAIL; _bufferPos = 0; @@ -189,7 +187,7 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) data = (void *)((Byte *)data + sizeTemp); size -= sizeTemp; processedSizeTotal += sizeTemp; - continue; + break; } int i; for (i = 0; _convertedPosEnd + i < _bufferPos; i++) @@ -198,7 +196,8 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) _convertedPosBegin = _convertedPosEnd = 0; UInt32 processedSizeTemp; UInt32 size0 = kBufferSize - _bufferPos; - RINOK(_inStream->Read(_buffer + _bufferPos, size0, &processedSizeTemp)); + // Optimize it: + RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp)); _bufferPos = _bufferPos + processedSizeTemp; _convertedPosEnd = Filter->Filter(_buffer, _bufferPos); if (_convertedPosEnd == 0) @@ -217,11 +216,6 @@ STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize) return S_OK; } -STDMETHODIMP CFilterCoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - // #endif // _ST_MODE #ifndef _NO_CRYPTO diff --git a/7zip/Archive/Common/FilterCoder.h b/7zip/Archive/Common/FilterCoder.h index a37e7715..4db7f28a 100755 --- a/7zip/Archive/Common/FilterCoder.h +++ b/7zip/Archive/Common/FilterCoder.h @@ -94,11 +94,9 @@ public: STDMETHOD(ReleaseInStream)(); STDMETHOD(SetInStream)(ISequentialInStream *inStream); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \ - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); \ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream); STDMETHOD(ReleaseOutStream)(); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Flush)(); // #endif diff --git a/7zip/Archive/Common/InStreamWithCRC.cpp b/7zip/Archive/Common/InStreamWithCRC.cpp index e1b98383..86151b9d 100755 --- a/7zip/Archive/Common/InStreamWithCRC.cpp +++ b/7zip/Archive/Common/InStreamWithCRC.cpp @@ -16,18 +16,6 @@ STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, return result; } -STDMETHODIMP CSequentialInStreamWithCRC::ReadPart(void *data, - UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); - _size += realProcessedSize; - _crc.Update(data, realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} - STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize) { @@ -40,18 +28,6 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, return result; } -STDMETHODIMP CInStreamWithCRC::ReadPart(void *data, - UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); - _size += realProcessedSize; - _crc.Update(data, realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} - STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { diff --git a/7zip/Archive/Common/InStreamWithCRC.h b/7zip/Archive/Common/InStreamWithCRC.h index 112af5d0..9628a6f2 100755 --- a/7zip/Archive/Common/InStreamWithCRC.h +++ b/7zip/Archive/Common/InStreamWithCRC.h @@ -15,7 +15,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); private: CMyComPtr<ISequentialInStream> _stream; UInt64 _size; @@ -40,7 +39,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); private: CMyComPtr<IInStream> _stream; diff --git a/7zip/Archive/Common/MultiStream.cpp b/7zip/Archive/Common/MultiStream.cpp index cdcb8886..7ef4f155 100755 --- a/7zip/Archive/Common/MultiStream.cpp +++ b/7zip/Archive/Common/MultiStream.cpp @@ -28,17 +28,11 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize) _pos += realProcessed; _seekPos += realProcessed; RINOK(result); - if (realProcessed == 0) - break; + break; } return S_OK; } -STDMETHODIMP CMultiStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { @@ -113,7 +107,6 @@ public: HRESULT Flush(); STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; HRESULT COutVolumeStream::Flush() @@ -179,17 +172,12 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce _streamIndex++; _offsetPos = 0; } - if (realProcessed != curSize) + if (realProcessed != curSize && realProcessed == 0) return E_FAIL; } return S_OK; } -STDMETHODIMP COutMultiStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { if(seekOrigin >= 3) diff --git a/7zip/Archive/Common/MultiStream.h b/7zip/Archive/Common/MultiStream.h index b6e2abc5..5a7cc687 100755 --- a/7zip/Archive/Common/MultiStream.h +++ b/7zip/Archive/Common/MultiStream.h @@ -36,7 +36,6 @@ public: MY_UNKNOWN_IMP1(IInStream) STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; @@ -70,7 +69,6 @@ public: MY_UNKNOWN_IMP1(IOutStream) STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; */ diff --git a/7zip/Archive/Common/OutStreamWithCRC.cpp b/7zip/Archive/Common/OutStreamWithCRC.cpp index ae832eef..4fbce564 100755 --- a/7zip/Archive/Common/OutStreamWithCRC.cpp +++ b/7zip/Archive/Common/OutStreamWithCRC.cpp @@ -7,24 +7,6 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) { - HRESULT result; - UInt32 realProcessedSize; - if(!_stream) - { - realProcessedSize = size; - result = S_OK; - } - else - result = _stream->Write(data, size, &realProcessedSize); - _crc.Update(data, realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} - -STDMETHODIMP COutStreamWithCRC::WritePart(const void *data, - UInt32 size, UInt32 *processedSize) -{ UInt32 realProcessedSize; HRESULT result; if(!_stream) @@ -33,7 +15,7 @@ STDMETHODIMP COutStreamWithCRC::WritePart(const void *data, result = S_OK; } else - result = _stream->WritePart(data, size, &realProcessedSize); + result = _stream->Write(data, size, &realProcessedSize); _crc.Update(data, realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; diff --git a/7zip/Archive/Common/OutStreamWithCRC.h b/7zip/Archive/Common/OutStreamWithCRC.h index 2668885c..23c69e04 100755 --- a/7zip/Archive/Common/OutStreamWithCRC.h +++ b/7zip/Archive/Common/OutStreamWithCRC.h @@ -15,7 +15,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CCRC _crc; CMyComPtr<ISequentialOutStream> _stream; diff --git a/7zip/Archive/Cpio/makefile b/7zip/Archive/Cpio/makefile index 6c5fb3f4..d7760281 100755 --- a/7zip/Archive/Cpio/makefile +++ b/7zip/Archive/Cpio/makefile @@ -14,6 +14,7 @@ COMMON_OBJS = \ $O\NewHandler.obj \ $O\String.obj \ $O\StringConvert.obj \ + $O\StringToInt.obj \ $O\Vector.obj \ WIN_OBJS = \ @@ -22,6 +23,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\LimitedStreams.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\ItemNameUtils.obj \ diff --git a/7zip/Archive/Deb/Deb.dsp b/7zip/Archive/Deb/Deb.dsp index 42f354a7..56689305 100755 --- a/7zip/Archive/Deb/Deb.dsp +++ b/7zip/Archive/Deb/Deb.dsp @@ -154,6 +154,14 @@ SOURCE=..\..\..\Common\StringConvert.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Vector.cpp # End Source File # Begin Source File @@ -248,6 +256,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/Archive/Deb/DebIn.cpp b/7zip/Archive/Deb/DebIn.cpp index 55f1e034..4900517b 100755 --- a/7zip/Archive/Deb/DebIn.cpp +++ b/7zip/Archive/Deb/DebIn.cpp @@ -5,8 +5,11 @@ #include "DebIn.h" #include "DebHeader.h" +#include "Common/StringToInt.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + namespace NArchive { namespace NDeb { @@ -14,7 +17,7 @@ using namespace NHeader; HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { - RINOK(m_Stream->Read(data, size, &processedSize)); + RINOK(ReadStream(m_Stream, data, size, &processedSize)); m_Position += processedSize; return S_OK; } @@ -24,7 +27,7 @@ HRESULT CInArchive::Open(IInStream *inStream) RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position)); char signature[kSignatureLen]; UInt32 processedSize; - RINOK(inStream->Read(signature, kSignatureLen, &processedSize)); + RINOK(ReadStream(inStream, signature, kSignatureLen, &processedSize)); m_Position += processedSize; if (processedSize != kSignatureLen) return S_FALSE; @@ -34,40 +37,50 @@ HRESULT CInArchive::Open(IInStream *inStream) return S_OK; } -static bool CheckString(const char *srcString, int numChars, int radix) +static bool OctalToNumber(const char *s, int size, UInt64 &res) { - for(int i = 0; i < numChars; i++) - { - char c = srcString[i]; - if (c == 0) - return true; - if (c >= '0' && c <= '0' + radix - 1) - continue; - if (c != ' ') - return false; - } - return true; + char sz[32]; + strncpy(sz, s, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *s, int size, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); } -static bool CheckOctalString(const char *srcString, int numChars) - { return CheckString(srcString, numChars, 8); } -static bool CheckDecimalString(const char *srcString, int numChars) - { return CheckString(srcString, numChars, 10); } -#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; } -#define ReturnIfBadDecimal(x, y) { if (!CheckDecimalString((x), (y))) return S_FALSE; } +static bool DecimalToNumber(const char *s, int size, UInt64 &res) +{ + char sz[32]; + strncpy(sz, s, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); +} -static UInt32 StringToNumber(const char *srcString, int numChars, int radix) +static bool DecimalToNumber32(const char *s, int size, UInt32 &res) { - AString modString; - for (int i = 0; i < numChars; i++) - modString += srcString[i]; - char *endPtr; - return strtoul(modString, &endPtr, radix); + UInt64 res64; + if (!DecimalToNumber(s, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); } -static UInt32 OctalToNumber(const char *srcString, int numChars) - { return StringToNumber(srcString, numChars, 8); } -static UInt32 DecimalToNumber(const char *srcString, int numChars) - { return StringToNumber(srcString, numChars, 10); } + +#define RIF(x) { if (!(x)) return S_FALSE; } + HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) { @@ -93,18 +106,15 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) if (((Byte)item.Name[i]) < 0x20) return S_FALSE; - ReturnIfBadDecimal(cur, kTimeSize); - item.ModificationTime = DecimalToNumber(cur, kTimeSize); + RIF(DecimalToNumber32(cur, kTimeSize, item.ModificationTime)); cur += kTimeSize; cur += 6 + 6; - ReturnIfBadOctal(cur, kModeSize); - item.Mode = OctalToNumber(cur, kModeSize); + RIF(OctalToNumber32(cur, kModeSize, item.Mode)); cur += kModeSize; - ReturnIfBadDecimal(cur, kSizeSize); - item.Size = DecimalToNumber(cur, kSizeSize); + RIF(DecimalToNumber(cur, kSizeSize, item.Size)); cur += kSizeSize; filled = true; diff --git a/7zip/Archive/Deb/DllExports.cpp b/7zip/Archive/Deb/DllExports.cpp index 66bf7c38..cb314000 100755 --- a/7zip/Archive/Deb/DllExports.cpp +++ b/7zip/Archive/Deb/DllExports.cpp @@ -8,9 +8,9 @@ #include "DebHandler.h" #include "../../ICoder.h" -// {23170F69-40C1-278A-1000-0001100C0000} +// {23170F69-40C1-278A-1000-000110EC0000} DEFINE_GUID(CLSID_CDebHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0C, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEC, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/Deb/makefile b/7zip/Archive/Deb/makefile index 8cff91a2..a74f33de 100755 --- a/7zip/Archive/Deb/makefile +++ b/7zip/Archive/Deb/makefile @@ -14,6 +14,7 @@ COMMON_OBJS = \ $O\NewHandler.obj \ $O\String.obj \ $O\StringConvert.obj \ + $O\StringToInt.obj \ $O\Vector.obj \ WIN_OBJS = \ @@ -22,6 +23,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\LimitedStreams.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\ItemNameUtils.obj \ diff --git a/7zip/Archive/GZip/DllExports.cpp b/7zip/Archive/GZip/DllExports.cpp index 4a0aca73..2b32f16b 100755 --- a/7zip/Archive/GZip/DllExports.cpp +++ b/7zip/Archive/GZip/DllExports.cpp @@ -8,9 +8,9 @@ #include "../../ICoder.h" #include "GZipHandler.h" -// {23170F69-40C1-278A-1000-000110030000} +// {23170F69-40C1-278A-1000-000110EF0000} DEFINE_GUID(CLSID_CGZipHandler, -0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00); +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEF, 0x00, 0x00); // {23170F69-40C1-278B-0401-080000000100} DEFINE_GUID(CLSID_CCompressDeflateEncoder, diff --git a/7zip/Archive/GZip/GZip.dsp b/7zip/Archive/GZip/GZip.dsp index aa880e63..4507e833 100755 --- a/7zip/Archive/GZip/GZip.dsp +++ b/7zip/Archive/GZip/GZip.dsp @@ -264,6 +264,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Archive Common" diff --git a/7zip/Archive/GZip/GZipHandler.cpp b/7zip/Archive/GZip/GZipHandler.cpp index f3d0d065..e234e96d 100755 --- a/7zip/Archive/GZip/GZipHandler.cpp +++ b/7zip/Archive/GZip/GZipHandler.cpp @@ -58,12 +58,14 @@ static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]); static const wchar_t *kUnknownOS = L"Unknown"; +/* enum // PropID { - // kpidExtraIsPresent = kpidUserDefined, - // kpidExtraFlags, - // kpidIsText + kpidExtraIsPresent = kpidUserDefined, + kpidExtraFlags, + kpidIsText }; +*/ STATPROPSTG kProperties[] = { diff --git a/7zip/Archive/GZip/GZipIn.cpp b/7zip/Archive/GZip/GZipIn.cpp index 69270fb1..d36ce5d0 100755 --- a/7zip/Archive/GZip/GZipIn.cpp +++ b/7zip/Archive/GZip/GZipIn.cpp @@ -8,13 +8,15 @@ #include "Common/MyCom.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + namespace NArchive { namespace NGZip { HRESULT CInArchive::ReadBytes(ISequentialInStream *inStream, void *data, UInt32 size) { UInt32 realProcessedSize; - RINOK(inStream->Read(data, size, &realProcessedSize)); + RINOK(ReadStream(inStream, data, size, &realProcessedSize)); m_Position += realProcessedSize; if(realProcessedSize != size) return S_FALSE; diff --git a/7zip/Archive/GZip/GZipOut.cpp b/7zip/Archive/GZip/GZipOut.cpp index e88ede19..99b08319 100755 --- a/7zip/Archive/GZip/GZipOut.cpp +++ b/7zip/Archive/GZip/GZipOut.cpp @@ -5,6 +5,7 @@ #include "GZipOut.h" #include "Common/CRC.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" namespace NArchive { namespace NGZip { @@ -12,7 +13,7 @@ namespace NGZip { HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) { UInt32 processedSize; - RINOK(m_Stream->Write(buffer, size, &processedSize)); + RINOK(WriteStream(m_Stream, buffer, size, &processedSize)); if(processedSize != size) return E_FAIL; return S_OK; diff --git a/7zip/Archive/GZip/makefile b/7zip/Archive/GZip/makefile index 3c1c94a5..06d8908d 100755 --- a/7zip/Archive/GZip/makefile +++ b/7zip/Archive/GZip/makefile @@ -26,6 +26,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CodecsPath.obj \ diff --git a/7zip/Archive/IArchive.h b/7zip/Archive/IArchive.h index 9c74b1bf..d6cbe804 100755 --- a/7zip/Archive/IArchive.h +++ b/7zip/Archive/IArchive.h @@ -7,6 +7,14 @@ #include "../IProgress.h" #include "../PropID.h" +// MIDL_INTERFACE("23170F69-40C1-278A-0000-000600xx0000") +#define ARCHIVE_INTERFACE_SUB(i, base, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, x, 0x00, 0x00); \ +struct i: public base + +#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x) + namespace NFileTimeType { enum EEnum @@ -29,6 +37,7 @@ namespace NArchive kKeepName, kStartSignature, kFinishSignature, + kAssociate }; namespace NExtract @@ -66,24 +75,15 @@ namespace NArchive } } -// {23170F69-40C1-278A-0000-000100010000} -DEFINE_GUID(IID_IArchiveOpenCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100010000") -IArchiveOpenCallback: public IUnknown +ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10) { -public: STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE; STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE; }; -// {23170F69-40C1-278A-0000-000100090000} -DEFINE_GUID(IID_IArchiveExtractCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100090000") -IArchiveExtractCallback: public IProgress + +ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20) { -public: STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) PURE; // GetStream OUT: S_OK - OK, S_FALSE - skeep this file @@ -92,36 +92,27 @@ public: }; -// {23170F69-40C1-278A-0000-0001000D0000} -DEFINE_GUID(IID_IArchiveOpenVolumeCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0000") -IArchiveOpenVolumeCallback: public IUnknown +ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30) { -public: STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE; STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE; }; -// {23170F69-40C1-278A-0000-0001000D0100} -DEFINE_GUID(IID_IArchiveOpenSetSubArchiveName, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x01, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000D0100") -IArchiveOpenSetSubArchiveName: public IUnknown +ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40) +{ + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; +}; + + +ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50) { -public: STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE; }; -// {23170F69-40C1-278A-0000-000100080000} -DEFINE_GUID(IID_IInArchive, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080000") -IInArchive: public IUnknown +ARCHIVE_INTERFACE(IInArchive, 0x60) { -public: STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) PURE; STDMETHOD(Close)() PURE; @@ -129,6 +120,9 @@ public: STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE; STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) PURE; + // indices must be sorted + // numItems = 0xFFFFFFFF means all files + // testMode != 0 means "test files operation" STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; @@ -141,25 +135,9 @@ public: BSTR *name, PROPID *propID, VARTYPE *varType) PURE; }; -// {23170F69-40C1-278A-0000-000100080100} -DEFINE_GUID(IID_IInArchiveGetStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x01, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100080100") -IInArchiveGetStream: public IUnknown -{ -public: - STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE; -}; - -// {23170F69-40C1-278A-0000-000100040000} -DEFINE_GUID(IID_IArchiveUpdateCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040000") -IArchiveUpdateCallback: public IProgress +ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80) { -public: - // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) PURE; STDMETHOD(GetUpdateItemInfo)(UInt32 index, Int32 *newData, // 1 - new data, 0 - old data Int32 *newProperties, // 1 - new properties, 0 - old properties @@ -170,33 +148,23 @@ public: STDMETHOD(SetOperationResult)(Int32 operationResult) PURE; }; -// {23170F69-40C1-278A-0000-000100040002} -DEFINE_GUID(IID_IArchiveUpdateCallback2, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100040002") -IArchiveUpdateCallback2: public IArchiveUpdateCallback + +ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82) { -public: STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE; STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE; }; -// {23170F69-40C1-278A-0000-000100020000} -DEFINE_GUID(IID_IOutArchive, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100020000") -IOutArchive: public IUnknown + +ARCHIVE_INTERFACE(IOutArchive, 0xA0) { STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) PURE; STDMETHOD(GetFileTimeType)(UInt32 *type) PURE; }; -// {23170F69-40C1-278A-0000-000100030000} -DEFINE_GUID(IID_ISetProperties, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000100030000") -ISetProperties: public IUnknown + +ARCHIVE_INTERFACE(ISetProperties, 0x03) { STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE; }; diff --git a/7zip/Archive/Lzh/DllExports.cpp b/7zip/Archive/Lzh/DllExports.cpp index 567d4bf8..ee5006f3 100755 --- a/7zip/Archive/Lzh/DllExports.cpp +++ b/7zip/Archive/Lzh/DllExports.cpp @@ -8,9 +8,9 @@ #include "../../ICoder.h" #include "LzhHandler.h" -// {23170F69-40C1-278A-1000-0001100E0000} +// {23170F69-40C1-278A-1000-000110060000} DEFINE_GUID(CLSID_CLzhHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0E, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/Lzh/Lzh.dsp b/7zip/Archive/Lzh/Lzh.dsp index 9f5b21b0..ad00699c 100755 --- a/7zip/Archive/Lzh/Lzh.dsp +++ b/7zip/Archive/Lzh/Lzh.dsp @@ -290,12 +290,28 @@ SOURCE=..\..\Common\MSBFDecoder.h # End Source File # Begin Source File +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + SOURCE=..\..\Common\ProgressUtils.cpp # End Source File # Begin Source File SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Archive Common" diff --git a/7zip/Archive/Lzh/LzhIn.cpp b/7zip/Archive/Lzh/LzhIn.cpp index f9b5daff..5344ef13 100755 --- a/7zip/Archive/Lzh/LzhIn.cpp +++ b/7zip/Archive/Lzh/LzhIn.cpp @@ -1,4 +1,4 @@ -/ Archive/arj/InEngine.cpp +// Archive/arj/InEngine.cpp #include "StdAfx.h" @@ -6,6 +6,8 @@ #include "Common/Buffer.h" #include "Common/CRC.h" +#include "../../Common/StreamUtils.h" + #include "LzhIn.h" namespace NArchive { @@ -13,7 +15,7 @@ namespace NLzh { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { - RINOK(m_Stream->Read(data, size, &processedSize)); + RINOK(ReadStream(m_Stream, data, size, &processedSize)); m_Position += processedSize; return S_OK; } diff --git a/7zip/Archive/Lzh/LzhItem.h b/7zip/Archive/Lzh/LzhItem.h index 36ccb672..b9b5f914 100755 --- a/7zip/Archive/Lzh/LzhItem.h +++ b/7zip/Archive/Lzh/LzhItem.h @@ -115,7 +115,14 @@ public: { int index = FindExt(kExtIdUnixTime); if (index < 0) + { + if (Level == 2) + { + value = ModifiedTime; + return true; + } return false; + } const Byte *data = (const Byte *)(Extensions[index].Data); value = data[0] | ((UInt32)data[1] << 8) | diff --git a/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp b/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp index ddefec88..2281a884 100755 --- a/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp +++ b/7zip/Archive/Lzh/LzhOutStreamWithCRC.cpp @@ -7,26 +7,7 @@ namespace NArchive { namespace NLzh { -STDMETHODIMP COutStreamWithCRC::Write(const void *data, - UInt32 size, UInt32 *processedSize) -{ - HRESULT result; - UInt32 realProcessedSize; - if(!_stream) - { - realProcessedSize = size; - result = S_OK; - } - else - result = _stream->Write(data, size, &realProcessedSize); - _crc.Update(data, realProcessedSize); - if(processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} - -STDMETHODIMP COutStreamWithCRC::WritePart(const void *data, - UInt32 size, UInt32 *processedSize) +STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; HRESULT result; @@ -36,7 +17,7 @@ STDMETHODIMP COutStreamWithCRC::WritePart(const void *data, result = S_OK; } else - result = _stream->WritePart(data, size, &realProcessedSize); + result = _stream->Write(data, size, &realProcessedSize); _crc.Update(data, realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; diff --git a/7zip/Archive/Lzh/LzhOutStreamWithCRC.h b/7zip/Archive/Lzh/LzhOutStreamWithCRC.h index fc5fc1c9..31b536b7 100755 --- a/7zip/Archive/Lzh/LzhOutStreamWithCRC.h +++ b/7zip/Archive/Lzh/LzhOutStreamWithCRC.h @@ -18,7 +18,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CCRC _crc; CMyComPtr<ISequentialOutStream> _stream; diff --git a/7zip/Archive/Lzh/makefile b/7zip/Archive/Lzh/makefile index caa61334..6f8fd2a0 100755 --- a/7zip/Archive/Lzh/makefile +++ b/7zip/Archive/Lzh/makefile @@ -23,7 +23,9 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\InBuffer.obj \ $O\LimitedStreams.obj \ + $O\OutBuffer.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\ItemNameUtils.obj \ diff --git a/7zip/Archive/RPM/DllExports.cpp b/7zip/Archive/RPM/DllExports.cpp index d712abfe..2319857c 100755 --- a/7zip/Archive/RPM/DllExports.cpp +++ b/7zip/Archive/RPM/DllExports.cpp @@ -8,9 +8,9 @@ #include "../../ICoder.h" #include "RpmHandler.h" -// {23170F69-40C1-278A-1000-000110090000} +// {23170F69-40C1-278A-1000-000110EB0000} DEFINE_GUID(CLSID_CRpmHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x09, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEB, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/RPM/Rpm.dsp b/7zip/Archive/RPM/Rpm.dsp index e0a828b3..085fe137 100755 --- a/7zip/Archive/RPM/Rpm.dsp +++ b/7zip/Archive/RPM/Rpm.dsp @@ -140,6 +140,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Compress" diff --git a/7zip/Archive/RPM/RpmIn.cpp b/7zip/Archive/RPM/RpmIn.cpp index 9b48a0ae..03373d9c 100755 --- a/7zip/Archive/RPM/RpmIn.cpp +++ b/7zip/Archive/RPM/RpmIn.cpp @@ -9,6 +9,8 @@ #include "Windows/Defs.h" #include "Common/MyCom.h" +#include "../../Common/StreamUtils.h" + namespace NArchive { namespace NRpm { @@ -31,7 +33,7 @@ static HRESULT RedSigHeaderSig(IInStream *inStream, CSigHeaderSig &h) char dat[kCSigHeaderSigSize]; char *cur = dat; UInt32 processedSize; - RINOK(inStream->Read(dat, kCSigHeaderSigSize, &processedSize)); + RINOK(ReadStream(inStream, dat, kCSigHeaderSigSize, &processedSize)); if (kCSigHeaderSigSize != processedSize) return S_FALSE; memmove(h.Magic, cur, 4); @@ -50,7 +52,7 @@ HRESULT OpenArchive(IInStream *inStream) char *cur = leadData; CLead lead; UInt32 processedSize; - RINOK(inStream->Read(leadData, kLeadSize, &processedSize)); + RINOK(ReadStream(inStream, leadData, kLeadSize, &processedSize)); if (kLeadSize != processedSize) return S_FALSE; memmove(lead.Magic, cur, 4); diff --git a/7zip/Archive/RPM/makefile b/7zip/Archive/RPM/makefile index 310c09a8..afda1289 100755 --- a/7zip/Archive/RPM/makefile +++ b/7zip/Archive/RPM/makefile @@ -17,6 +17,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ OBJS = \ $O\StdAfx.obj \ diff --git a/7zip/Archive/Rar/DllExports.cpp b/7zip/Archive/Rar/DllExports.cpp index 7e24047c..0df1ac47 100755 --- a/7zip/Archive/Rar/DllExports.cpp +++ b/7zip/Archive/Rar/DllExports.cpp @@ -46,9 +46,9 @@ DEFINE_GUID(CLSID_CCryptoRar29Decoder, 0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00); */ -// {23170F69-40C1-278A-1000-000110020000} +// {23170F69-40C1-278A-1000-000110030000} DEFINE_GUID(CLSID_CRarHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/Rar/Rar.dsp b/7zip/Archive/Rar/Rar.dsp index 9fe9b840..9aee468e 100755 --- a/7zip/Archive/Rar/Rar.dsp +++ b/7zip/Archive/Rar/Rar.dsp @@ -178,6 +178,14 @@ SOURCE=..\..\..\Common\Types.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Vector.cpp # End Source File # Begin Source File @@ -400,6 +408,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "7z" diff --git a/7zip/Archive/Rar/RarHandler.cpp b/7zip/Archive/Rar/RarHandler.cpp index d38b65a4..56187156 100755 --- a/7zip/Archive/Rar/RarHandler.cpp +++ b/7zip/Archive/Rar/RarHandler.cpp @@ -186,7 +186,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va switch(propID) { case kpidPath: - if (item.HasUnicodeName()) + if (item.HasUnicodeName() && !item.UnicodeName.IsEmpty()) propVariant = item.UnicodeName; else propVariant = (const wchar_t *)MultiByteToUnicodeString(item.Name, CP_OEMCP); @@ -615,6 +615,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, NCrypto::NRar20::CDecoder *rar20CryptoDecoderSpec; CMyComPtr<ICompressFilter> rar20CryptoDecoder; + NCrypto::NRar29::CDecoder *rar29CryptoDecoderSpec; CMyComPtr<ICompressFilter> rar29CryptoDecoder; CFolderInStream *folderInStreamSpec = NULL; @@ -727,9 +728,11 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, { if (!rar29CryptoDecoder) { - rar29CryptoDecoder = new NCrypto::NRar29::CDecoder; + rar29CryptoDecoderSpec = new NCrypto::NRar29::CDecoder; + rar29CryptoDecoder = rar29CryptoDecoderSpec; // RINOK(rar29CryptoDecoder.CoCreateInstance(CLSID_CCryptoRar29Decoder)); } + rar29CryptoDecoderSpec->SetRar350Mode(item.UnPackVersion < 36); CMyComPtr<ICompressSetDecoderProperties2> cryptoProperties; RINOK(rar29CryptoDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &cryptoProperties)); diff --git a/7zip/Archive/Rar/RarHeader.h b/7zip/Archive/Rar/RarHeader.h index f7e6f711..832a21c0 100755 --- a/7zip/Archive/Rar/RarHeader.h +++ b/7zip/Archive/Rar/RarHeader.h @@ -42,7 +42,10 @@ namespace NArchive const UInt16 kRecovery = 0x40; const UInt16 kBlockEncryption = 0x80; const UInt16 kFirstVolume = 0x100; // (set only by RAR 3.0 and later) + const UInt16 kEncryptVer = 0x200; // RAR 3.6 there is EncryptVer Byte in End of MainHeader + const int kHeaderSizeMin = 7; + struct CBlock { UInt16 CRC; @@ -53,9 +56,19 @@ namespace NArchive UInt32 Reserved2; // UInt16 GetRealCRC() const; }; + const int kArchiveHeaderSize = 13; const int kBlockHeadersAreEncrypted = 0x80; + + struct CHeader360: public CBlock + { + Byte EncryptVersion; + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } + bool IsThereEncryptVer() const { return (Flags & NHeader::NArchive::kEncryptVer) != 0; } + bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } + UInt32 GetBaseSize() const { return kArchiveHeaderSize + (IsEncryptOld() ? 0 : 1); } + }; } namespace NFile diff --git a/7zip/Archive/Rar/RarIn.cpp b/7zip/Archive/Rar/RarIn.cpp index f6a4891f..36d8b824 100755 --- a/7zip/Archive/Rar/RarIn.cpp +++ b/7zip/Archive/Rar/RarIn.cpp @@ -4,9 +4,11 @@ #include "Common/StringConvert.h" #include "Common/CRC.h" +#include "Common/UTFConvert.h" #include "RarIn.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" namespace NArchive { namespace NRar { @@ -115,7 +117,7 @@ bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size) return (i == size); } UInt32 processedSize; - m_Stream->Read(data, size, &processedSize); + ReadStream(m_Stream, data, size, &processedSize); return (processedSize == size); } @@ -128,7 +130,7 @@ void CInArchive::ReadBytesAndTestResult(void *data, UInt32 size) HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; - HRESULT result = m_Stream->Read(data, size, &realProcessedSize); + HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; AddToSeekValue(realProcessedSize); @@ -155,6 +157,7 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) m_ArchiveHeader.Size = ReadUInt16(); m_ArchiveHeader.Reserved1 = ReadUInt16(); m_ArchiveHeader.Reserved2 = ReadUInt32(); + m_ArchiveHeader.EncryptVersion = 0; CCRC crc; crc.UpdateByte(m_ArchiveHeader.Type); @@ -163,6 +166,14 @@ bool CInArchive::ReadMarkerAndArchiveHeader(const UInt64 *searchHeaderSizeLimit) crc.UpdateUInt16(m_ArchiveHeader.Reserved1); crc.UpdateUInt32(m_ArchiveHeader.Reserved2); + if (m_ArchiveHeader.IsThereEncryptVer() && m_ArchiveHeader.Size > NHeader::NArchive::kArchiveHeaderSize) + { + ReadBytes(&m_ArchiveHeader.EncryptVersion, 1, &processedSize); + if (processedSize != 1) + return false; + crc.UpdateByte(m_ArchiveHeader.EncryptVersion); + } + UInt32 u = crc.GetDigest(); if(m_ArchiveHeader.CRC != (crc.GetDigest() & 0xFFFF)) ThrowExceptionWithCode(CInArchiveException::kArchiveHeaderCRCError); @@ -177,7 +188,7 @@ void CInArchive::SkipArchiveComment() { if (!m_SeekOnArchiveComment) return; - AddToSeekValue(m_ArchiveHeader.Size - NHeader::NArchive::kArchiveHeaderSize); + AddToSeekValue(m_ArchiveHeader.Size - m_ArchiveHeader.GetBaseSize()); m_SeekOnArchiveComment = false; } @@ -256,15 +267,18 @@ void CInArchive::ReadName(CItemEx &item, int nameSize) buffer[mainLen] = '\0'; item.Name = buffer; - int unicodeNameSizeMax = MyMin(nameSize, (0x400)); - _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1); - - if((m_BlockHeader.Flags & NHeader::NFile::kUnicodeName) != 0 && - mainLen < nameSize) + if(item.HasUnicodeName()) { - DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, - nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); - item.UnicodeName = _unicodeNameBuffer; + if(mainLen < nameSize) + { + int unicodeNameSizeMax = MyMin(nameSize, (0x400)); + _unicodeNameBuffer.EnsureCapacity(unicodeNameSizeMax + 1); + DecodeUnicodeFileName(buffer, (const Byte *)buffer + mainLen + 1, + nameSize - (mainLen + 1), _unicodeNameBuffer, unicodeNameSizeMax); + item.UnicodeName = _unicodeNameBuffer; + } + else if (!ConvertUTF8ToUnicode(item.Name, item.UnicodeName)) + item.UnicodeName.Empty(); } } else @@ -398,6 +412,8 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa m_RarAESSpec = new NCrypto::NRar29::CDecoder; m_RarAES = m_RarAESSpec; } + m_RarAESSpec->SetRar350Mode(m_ArchiveHeader.IsEncryptOld()); + // Salt const UInt32 kSaltSize = 8; Byte salt[kSaltSize]; @@ -410,9 +426,17 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa RINOK(getTextPassword->CryptoGetTextPassword(&password)) UString unicodePassword(password); - RINOK(m_RarAESSpec->CryptoSetPassword( - (const Byte *)(const wchar_t *)unicodePassword, - unicodePassword.Length() * 2)); + CByteBuffer buffer; + const UInt32 sizeInBytes = unicodePassword.Length() * 2; + buffer.SetCapacity(sizeInBytes); + for (int i = 0; i < unicodePassword.Length(); i++) + { + wchar_t c = unicodePassword[i]; + ((Byte *)buffer)[i * 2] = (Byte)c; + ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); + } + + RINOK(m_RarAESSpec->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); const UInt32 kDecryptedBufferSize = (1 << 12); if (m_DecryptedData.GetCapacity() == 0) @@ -420,7 +444,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa m_DecryptedData.SetCapacity(kDecryptedBufferSize); } RINOK(m_RarAES->Init()); - RINOK(m_Stream->Read((Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize)); + RINOK(ReadStream(m_Stream, (Byte *)m_DecryptedData, kDecryptedBufferSize, &m_DecryptedDataSize)); m_DecryptedDataSize = m_RarAES->Filter((Byte *)m_DecryptedData, m_DecryptedDataSize); m_CryptoMode = true; @@ -486,7 +510,7 @@ HRESULT CInArchive::GetNextItem(CItemEx &item, ICryptoGetTextPassword *getTextPa void CInArchive::DirectGetBytes(void *data, UInt32 size) { - m_Stream->Read(data, size, NULL); + ReadStream(m_Stream, data, size, NULL); } bool CInArchive::SeekInArchive(UInt64 position) diff --git a/7zip/Archive/Rar/RarIn.h b/7zip/Archive/Rar/RarIn.h index c370733a..22262a74 100755 --- a/7zip/Archive/Rar/RarIn.h +++ b/7zip/Archive/Rar/RarIn.h @@ -41,6 +41,7 @@ public: bool IsCommented() const { return (Flags & NHeader::NArchive::kComment) != 0; } bool IsVolume() const { return (Flags & NHeader::NArchive::kVolume) != 0; } bool HaveNewVolumeName() const { return (Flags & NHeader::NArchive::kNewVolName) != 0; } + bool IsEncrypted() const { return (Flags & NHeader::NArchive::kBlockEncryption) != 0; } }; class CInArchive @@ -51,7 +52,7 @@ class CInArchive UInt64 m_Position; UInt64 m_ArchiveStartPosition; - NHeader::NArchive::CBlock m_ArchiveHeader; + NHeader::NArchive::CHeader360 m_ArchiveHeader; CDynamicBuffer<char> m_NameBuffer; CDynamicBuffer<wchar_t> _unicodeNameBuffer; bool m_SeekOnArchiveComment; diff --git a/7zip/Archive/Rar/RarVolumeInStream.cpp b/7zip/Archive/Rar/RarVolumeInStream.cpp index 5a185707..32078e6d 100755 --- a/7zip/Archive/Rar/RarVolumeInStream.cpp +++ b/7zip/Archive/Rar/RarVolumeInStream.cpp @@ -64,6 +64,7 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz } realProcessedSize += localProcessedSize; size -= localProcessedSize; + break; } else { @@ -75,9 +76,4 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz return S_OK; } -STDMETHODIMP CFolderInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - -}}
\ No newline at end of file +}} diff --git a/7zip/Archive/Rar/RarVolumeInStream.h b/7zip/Archive/Rar/RarVolumeInStream.h index 53156306..4c9a9e96 100755 --- a/7zip/Archive/Rar/RarVolumeInStream.h +++ b/7zip/Archive/Rar/RarVolumeInStream.h @@ -25,7 +25,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); private: CObjectVector<CInArchive> *_archives; diff --git a/7zip/Archive/Rar/makefile b/7zip/Archive/Rar/makefile index 0799edf3..42942f74 100755 --- a/7zip/Archive/Rar/makefile +++ b/7zip/Archive/Rar/makefile @@ -18,6 +18,7 @@ COMMON_OBJS = \ $O\NewHandler.obj \ $O\String.obj \ $O\StringConvert.obj \ + $O\UTFConvert.obj \ $O\Vector.obj \ WIN_OBJS = \ @@ -29,6 +30,7 @@ WIN_OBJS = \ $O\LimitedStreams.obj \ $O\ProgressUtils.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CodecsPath.obj \ diff --git a/7zip/Archive/Split/DllExports.cpp b/7zip/Archive/Split/DllExports.cpp index d8ea97c7..f9e8a83b 100755 --- a/7zip/Archive/Split/DllExports.cpp +++ b/7zip/Archive/Split/DllExports.cpp @@ -8,9 +8,9 @@ #include "SplitHandler.h" #include "../../ICoder.h" -// {23170F69-40C1-278A-1000-0001100B0000} +// {23170F69-40C1-278A-1000-000110EA0000} DEFINE_GUID(CLSID_CSplitHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0B, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEA, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/Split/Split.dsp b/7zip/Archive/Split/Split.dsp index 5758e3b3..d6229d98 100755 --- a/7zip/Archive/Split/Split.dsp +++ b/7zip/Archive/Split/Split.dsp @@ -204,6 +204,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Interface" @@ -223,7 +231,7 @@ SOURCE=.\SplitHandler.h # End Source File # Begin Source File -SOURCE=.\SplitHanlerOut.cpp +SOURCE=.\SplitHandlerOut.cpp # End Source File # End Target # End Project diff --git a/7zip/Archive/Split/makefile b/7zip/Archive/Split/makefile index a821b2f8..650c750b 100755 --- a/7zip/Archive/Split/makefile +++ b/7zip/Archive/Split/makefile @@ -20,6 +20,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\MultiStream.obj \ diff --git a/7zip/Archive/Tar/DllExports.cpp b/7zip/Archive/Tar/DllExports.cpp index 7f4f5c04..9d80a651 100755 --- a/7zip/Archive/Tar/DllExports.cpp +++ b/7zip/Archive/Tar/DllExports.cpp @@ -8,9 +8,9 @@ #include "../../ICoder.h" #include "TarHandler.h" -// {23170F69-40C1-278A-1000-000110040000} +// {23170F69-40C1-278A-1000-000110EE0000} DEFINE_GUID(CLSID_CTarHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xEE, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/Tar/Tar.dsp b/7zip/Archive/Tar/Tar.dsp index bba8ab2b..c01e7383 100755 --- a/7zip/Archive/Tar/Tar.dsp +++ b/7zip/Archive/Tar/Tar.dsp @@ -162,6 +162,14 @@ SOURCE=..\..\..\Common\StringConvert.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Vector.cpp # End Source File # Begin Source File @@ -276,6 +284,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/Archive/Tar/TarHeader.cpp b/7zip/Archive/Tar/TarHeader.cpp index 9bf408c0..41fb2137 100755 --- a/7zip/Archive/Tar/TarHeader.cpp +++ b/7zip/Archive/Tar/TarHeader.cpp @@ -16,7 +16,7 @@ namespace NFileHeader { // The magic field is filled with this if uname and gname are valid. namespace NMagic { - const char *kUsTar = "ustar "; // 7 chars and a null + const char *kUsTar = "ustar"; // 5 chars const char *kGNUTar = "GNUtar "; // 7 chars and a null const char *kEmpty = "\0\0\0\0\0\0\0\0"; // 7 chars and a null } diff --git a/7zip/Archive/Tar/TarHeader.h b/7zip/Archive/Tar/TarHeader.h index c32092ca..1436293f 100755 --- a/7zip/Archive/Tar/TarHeader.h +++ b/7zip/Archive/Tar/TarHeader.h @@ -14,6 +14,7 @@ namespace NFileHeader const int kNameSize = 100; const int kUserNameSize = 32; const int kGroupNameSize = 32; + const int kPrefixSize = 155; /* struct CHeader @@ -32,6 +33,7 @@ namespace NFileHeader char GroupName[kGroupNameSize]; char DeviceMajor[8]; char DeviceMinor[8]; + char Prefix[155]; }; union CRecord { @@ -84,7 +86,7 @@ namespace NFileHeader // The magic field is filled with this if uname and gname are valid. namespace NMagic { - extern const char *kUsTar; // = "ustar "; // 7 chars and a null + extern const char *kUsTar; // = "ustar"; // 5 chars extern const char *kGNUTar; // = "GNUtar "; // 7 chars and a null extern const char *kEmpty; // = "GNUtar "; // 7 chars and a null } diff --git a/7zip/Archive/Tar/TarIn.cpp b/7zip/Archive/Tar/TarIn.cpp index f9bfacd6..fad27587 100755 --- a/7zip/Archive/Tar/TarIn.cpp +++ b/7zip/Archive/Tar/TarIn.cpp @@ -5,14 +5,17 @@ #include "TarIn.h" #include "TarHeader.h" +#include "Common/StringToInt.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + namespace NArchive { namespace NTar { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { - RINOK(m_Stream->Read(data, size, &processedSize)); + RINOK(ReadStream(m_Stream, data, size, &processedSize)); m_Position += processedSize; return S_OK; } @@ -24,28 +27,28 @@ HRESULT CInArchive::Open(IInStream *inStream) return S_OK; } -static UInt32 OctalToNumber(const char *srcString) +static bool OctalToNumber(const char *srcString, int size, UInt64 &res) { - char *endPtr; - return(strtoul(srcString, &endPtr, 8)); + char sz[32]; + strncpy(sz, srcString, size); + sz[size] = 0; + const char *end; + int i; + for (i = 0; sz[i] == ' '; i++); + res = ConvertOctStringToUInt64(sz + i, &end); + return (*end == ' ' || *end == 0); } -static bool CheckOctalString(const char *srcString, int numChars) +static bool OctalToNumber32(const char *srcString, int size, UInt32 &res) { - for(int i = 0; i < numChars; i++) - { - char c = srcString[i]; - if (c == 0) - return true; - if (c >= '0' && c <= '7') - continue; - if (c != ' ') - return false; - } - return true; + UInt64 res64; + if (!OctalToNumber(srcString, size, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); } -#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; } +#define RIF(x) { if (!(x)) return S_FALSE; } static bool IsRecordLast(const char *record) { @@ -57,9 +60,9 @@ static bool IsRecordLast(const char *record) static void ReadString(const char *s, int size, AString &result) { - if (size > NFileHeader::kNameSize) + if (size > NFileHeader::kRecordSize) size = NFileHeader::kNameSize; - char tempString[NFileHeader::kNameSize + 1]; + char tempString[NFileHeader::kRecordSize + 1]; strncpy(tempString, s, size); tempString[size] = '\0'; result = tempString; @@ -114,28 +117,23 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) item.Name += c; } - ReturnIfBadOctal(cur, 8); - item.Mode = OctalToNumber(cur); + RIF(OctalToNumber32(cur, 8, item.Mode)); cur += 8; - ReturnIfBadOctal(cur, 8); - item.UID = OctalToNumber(cur); + RIF(OctalToNumber32(cur, 8, item.UID)); cur += 8; - ReturnIfBadOctal(cur, 8); - item.GID = OctalToNumber(cur); + RIF(OctalToNumber32(cur, 8, item.GID)); cur += 8; - ReturnIfBadOctal(cur, 12); - item.Size = OctalToNumber(cur); + RIF(OctalToNumber(cur, 12, item.Size)); cur += 12; - ReturnIfBadOctal(cur, 12); - item.ModificationTime = OctalToNumber(cur); + RIF(OctalToNumber32(cur, 12, item.ModificationTime)); cur += 12; - ReturnIfBadOctal(cur, 8); - UInt32 checkSum = OctalToNumber(cur); + UInt32 checkSum; + RIF(OctalToNumber32(cur, 8, checkSum)); memmove(cur, NFileHeader::kCheckSumBlanks, 8); cur += 8; @@ -153,17 +151,19 @@ HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item) ReadString(cur, NFileHeader::kUserNameSize, item.GroupName); cur += NFileHeader::kUserNameSize; - ReturnIfBadOctal(cur, 8); item.DeviceMajorDefined = (cur[0] != 0); - if (item.DeviceMajorDefined) - item.DeviceMajor = OctalToNumber(cur); + RIF(OctalToNumber32(cur, 8, item.DeviceMajor)); + cur += 8; - ReturnIfBadOctal(cur, 8); item.DeviceMinorDefined = (cur[0] != 0); - if (item.DeviceMinorDefined) - item.DeviceMinor = OctalToNumber(cur); + RIF(OctalToNumber32(cur, 8, item.DeviceMinor)); cur += 8; + AString prefix; + ReadString(cur, NFileHeader::kPrefixSize, prefix); + cur += NFileHeader::kPrefixSize; + if (!prefix.IsEmpty() && item.IsMagic()) + item.Name = prefix + AString('/') + item.Name; if (item.LinkFlag == NFileHeader::NLinkFlag::kLink) item.Size = 0; diff --git a/7zip/Archive/Tar/TarItem.h b/7zip/Archive/Tar/TarItem.h index 7637b537..71fff7ba 100755 --- a/7zip/Archive/Tar/TarItem.h +++ b/7zip/Archive/Tar/TarItem.h @@ -45,6 +45,14 @@ public: } return false; } + + bool IsMagic() const + { + for (int i = 0; i < 5; i++) + if (Magic[i] != NFileHeader::NMagic::kUsTar[i]) + return false; + return true; + } }; class CItemEx: public CItem diff --git a/7zip/Archive/Tar/TarOut.cpp b/7zip/Archive/Tar/TarOut.cpp index 45c7ef1d..28146c34 100755 --- a/7zip/Archive/Tar/TarOut.cpp +++ b/7zip/Archive/Tar/TarOut.cpp @@ -7,6 +7,7 @@ #include "Common/IntToString.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" namespace NArchive { namespace NTar { @@ -14,7 +15,7 @@ namespace NTar { HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size) { UInt32 processedSize; - RINOK(m_Stream->Write(buffer, size, &processedSize)); + RINOK(WriteStream(m_Stream, buffer, size, &processedSize)); if(processedSize != size) return E_FAIL; return S_OK; @@ -165,10 +166,15 @@ HRESULT COutArchive::FillDataResidual(UInt64 dataSize) HRESULT COutArchive::WriteFinishHeader() { - char record[NFileHeader::kRecordSize]; - for (int i = 0; i < NFileHeader::kRecordSize; i++) + Byte record[NFileHeader::kRecordSize]; + int i; + for (i = 0; i < NFileHeader::kRecordSize; i++) record[i] = 0; - return WriteBytes(record, NFileHeader::kRecordSize); + for (i = 0; i < 2; i++) + { + RINOK(WriteBytes(record, NFileHeader::kRecordSize)); + } + return S_OK; } }} diff --git a/7zip/Archive/Tar/makefile b/7zip/Archive/Tar/makefile index b9670b28..f892c303 100755 --- a/7zip/Archive/Tar/makefile +++ b/7zip/Archive/Tar/makefile @@ -18,6 +18,7 @@ COMMON_OBJS = \ $O\NewHandler.obj \ $O\String.obj \ $O\StringConvert.obj \ + $O\StringToInt.obj \ $O\Vector.obj \ WIN_OBJS = \ @@ -26,6 +27,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\LimitedStreams.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\ItemNameUtils.obj \ diff --git a/7zip/Archive/Z/DllExports.cpp b/7zip/Archive/Z/DllExports.cpp index 7d4e0d23..d96cd303 100755 --- a/7zip/Archive/Z/DllExports.cpp +++ b/7zip/Archive/Z/DllExports.cpp @@ -8,13 +8,9 @@ #include "ZHandler.h" #include "../../ICoder.h" -// {23170F69-40C1-278B-0402-050000000000} -DEFINE_GUID(CLSID_CCompressZDecoder, -0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00); - -// {23170F69-40C1-278A-1000-0001100D0000} +// {23170F69-40C1-278A-1000-000110050000} DEFINE_GUID(CLSID_CZHandler, -0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x0D, 0x00, 0x00); +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); HINSTANCE g_hInstance; diff --git a/7zip/Archive/Z/Z.dsp b/7zip/Archive/Z/Z.dsp index 56873229..e1f72522 100755 --- a/7zip/Archive/Z/Z.dsp +++ b/7zip/Archive/Z/Z.dsp @@ -220,6 +220,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Source File diff --git a/7zip/Archive/Z/ZHandler.cpp b/7zip/Archive/Z/ZHandler.cpp index e7b13a75..5787273b 100755 --- a/7zip/Archive/Z/ZHandler.cpp +++ b/7zip/Archive/Z/ZHandler.cpp @@ -8,6 +8,7 @@ #include "../../Common/ProgressUtils.h" #include "../../Compress/Z/ZDecoder.h" +#include "../../Common/StreamUtils.h" #include "Windows/PropVariant.h" #include "Windows/Defs.h" @@ -98,7 +99,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream, RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition)); Byte buffer[kSignatureSize]; UInt32 processedSize; - RINOK(stream->Read(buffer, kSignatureSize, &processedSize)); + RINOK(ReadStream(stream, buffer, kSignatureSize, &processedSize)); if (processedSize != kSignatureSize) return S_FALSE; if (buffer[0] != 0x1F || buffer[1] != 0x9D) diff --git a/7zip/Archive/Z/makefile b/7zip/Archive/Z/makefile index fbd9d6ad..aff4fc42 100755 --- a/7zip/Archive/Z/makefile +++ b/7zip/Archive/Z/makefile @@ -18,6 +18,7 @@ WIN_OBJS = \ $O\InBuffer.obj \ $O\OutBuffer.obj \ $O\ProgressUtils.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\DummyOutStream.obj \ diff --git a/7zip/Archive/Zip/Zip.dsp b/7zip/Archive/Zip/Zip.dsp index 7a5ebdbf..44852ec1 100755 --- a/7zip/Archive/Zip/Zip.dsp +++ b/7zip/Archive/Zip/Zip.dsp @@ -320,6 +320,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Engine" diff --git a/7zip/Archive/Zip/ZipHandler.cpp b/7zip/Archive/Zip/ZipHandler.cpp index 922a69c7..00a61f57 100755 --- a/7zip/Archive/Zip/ZipHandler.cpp +++ b/7zip/Archive/Zip/ZipHandler.cpp @@ -148,6 +148,7 @@ const wchar_t *kMethods[] = const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]); const wchar_t *kUnknownMethod = L"Unknown"; +const wchar_t *kPPMdMethod = L"PPMd"; CHandler::CHandler(): m_ArchiveIsOpen(false) @@ -258,6 +259,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID aPropID, PROPVARIANT *a UString method; if (item.CompressionMethod < kNumMethods) method = kMethods[item.CompressionMethod]; + else if (item.CompressionMethod == NFileHeader::NCompressionMethod::kWinZipPPMd) + method = kPPMdMethod; else method = kUnknownMethod; propVariant = method; diff --git a/7zip/Archive/Zip/ZipHeader.h b/7zip/Archive/Zip/ZipHeader.h index e6d1288a..7d023715 100755 --- a/7zip/Archive/Zip/ZipHeader.h +++ b/7zip/Archive/Zip/ZipHeader.h @@ -67,7 +67,8 @@ namespace NFileHeader kDeflated64 = 9, kPKImploding = 10, - kBZip2 = 12 + kBZip2 = 12, + kWinZipPPMd = 0x62 }; const int kNumCompressionMethods = 11; const Byte kMadeByProgramVersion = 20; diff --git a/7zip/Archive/Zip/ZipIn.cpp b/7zip/Archive/Zip/ZipIn.cpp index 4b4481ed..59f1e0ae 100755 --- a/7zip/Archive/Zip/ZipIn.cpp +++ b/7zip/Archive/Zip/ZipIn.cpp @@ -7,6 +7,7 @@ #include "Common/StringConvert.h" #include "Common/DynamicBuffer.h" #include "../../Common/LimitedStreams.h" +#include "../../Common/StreamUtils.h" namespace NArchive { namespace NZip { @@ -87,13 +88,10 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit) } } -////////////////////////////////////// -// Read Operations - HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; - HRESULT result = m_Stream->Read(data, size, &realProcessedSize); + HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; m_Position += realProcessedSize; @@ -158,9 +156,6 @@ UInt64 CInArchive::ReadUInt64() return value; } -////////////////////////////////// -// Read headers - bool CInArchive::ReadUInt32(UInt32 &value) { value = 0; diff --git a/7zip/Archive/Zip/ZipOut.cpp b/7zip/Archive/Zip/ZipOut.cpp index 7e46d6ca..6e4e7335 100755 --- a/7zip/Archive/Zip/ZipOut.cpp +++ b/7zip/Archive/Zip/ZipOut.cpp @@ -6,6 +6,7 @@ #include "Common/StringConvert.h" #include "Common/CRC.h" #include "../../Common/OffsetStream.h" +#include "../../Common/StreamUtils.h" namespace NArchive { namespace NZip { @@ -46,7 +47,7 @@ void COutArchive::PrepareWriteCompressedData2(UInt16 fileNameLength, UInt64 unPa void COutArchive::WriteBytes(const void *buffer, UInt32 size) { UInt32 processedSize; - if(m_Stream->Write(buffer, size, &processedSize) != S_OK) + if(WriteStream(m_Stream, buffer, size, &processedSize) != S_OK) throw 0; if(processedSize != size) throw 0; diff --git a/7zip/Archive/Zip/makefile b/7zip/Archive/Zip/makefile index 22d59801..4d59fb0c 100755 --- a/7zip/Archive/Zip/makefile +++ b/7zip/Archive/Zip/makefile @@ -38,6 +38,7 @@ WIN_OBJS = \ $O\OutBuffer.obj \ $O\ProgressUtils.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CodecsPath.obj \ diff --git a/7zip/Archive/cpio/CpioIn.cpp b/7zip/Archive/cpio/CpioIn.cpp index ce2ab023..32b9f77d 100755 --- a/7zip/Archive/cpio/CpioIn.cpp +++ b/7zip/Archive/cpio/CpioIn.cpp @@ -4,8 +4,11 @@ #include "CpioIn.h" +#include "Common/StringToInt.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + #include "CpioHeader.h" namespace NArchive { @@ -13,7 +16,7 @@ namespace NCpio { HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize) { - RINOK(m_Stream->Read(data, size, &processedSize)); + RINOK(ReadStream(m_Stream, data, size, &processedSize)); m_Position += processedSize; return S_OK; } @@ -75,24 +78,37 @@ bool CInArchive::ReadNumber(UInt32 &resultValue) return true; } +static bool OctalToNumber(const char *s, UInt64 &res) +{ + const char *end; + res = ConvertOctStringToUInt64(s, &end); + return (*end == ' ' || *end == 0); +} + +static bool OctalToNumber32(const char *s, UInt32 &res) +{ + UInt64 res64; + if (!OctalToNumber(s, res64)) + return false; + res = (UInt32)res64; + return (res64 <= 0xFFFFFFFF); +} + bool CInArchive::ReadOctNumber(int size, UInt32 &resultValue) { - char s[32]; + char sz[32 + 4]; int i; for (i = 0; i < size && i < 32; i++) - s[i] = char(ReadByte()); - s[i] = 0; - char *endPtr; - resultValue = strtoul(s, &endPtr, 8); - return true; + sz[i] = (char)ReadByte(); + sz[i] = 0; + return OctalToNumber32(sz, resultValue); } -#define GetFromHex(y) { if (!ReadNumber(y)) return E_FAIL; } -#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return E_FAIL; } -#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return E_FAIL; } +#define GetFromHex(y) { if (!ReadNumber(y)) return S_FALSE; } +#define GetFromOct6(y) { if (!ReadOctNumber(6, y)) return S_FALSE; } +#define GetFromOct11(y) { if (!ReadOctNumber(11, y)) return S_FALSE; } -static unsigned short ConvertValue( - unsigned short value, bool convert) +static unsigned short ConvertValue(unsigned short value, bool convert) { if (!convert) return value; @@ -109,13 +125,6 @@ static UInt32 GetAlignedSize(UInt32 size, UInt32 align) HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item) { - /* - union - { - NFileHeader::CRecord record; - NFileHeader::CRecord2 record2; - }; - */ filled = false; UInt32 processedSize; diff --git a/7zip/Archive/cpio/DllExports.cpp b/7zip/Archive/cpio/DllExports.cpp index a72058a5..32473235 100755 --- a/7zip/Archive/cpio/DllExports.cpp +++ b/7zip/Archive/cpio/DllExports.cpp @@ -8,9 +8,9 @@ #include "CpioHandler.h" #include "../../ICoder.h" -// {23170F69-40C1-278A-1000-000110080000} +// {23170F69-40C1-278A-1000-000110ED0000} DEFINE_GUID(CLSID_CCpioHandler, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0xED, 0x00, 0x00); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) diff --git a/7zip/Archive/cpio/cpio.dsp b/7zip/Archive/cpio/cpio.dsp index 5f555d9b..f30c3e63 100755 --- a/7zip/Archive/cpio/cpio.dsp +++ b/7zip/Archive/cpio/cpio.dsp @@ -150,6 +150,14 @@ SOURCE=..\..\..\Common\StringConvert.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Vector.cpp # End Source File # Begin Source File @@ -244,6 +252,14 @@ SOURCE=..\..\Common\ProgressUtils.cpp SOURCE=..\..\Common\ProgressUtils.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/Archive/makefile b/7zip/Archive/makefile index a5858144..24df1961 100755 --- a/7zip/Archive/makefile +++ b/7zip/Archive/makefile @@ -3,6 +3,7 @@ DIRS = \ Arj\~ \ BZip2\~ \ Cab\~ \ + Chm\~ \ Cpio\~ \ Deb\~ \ GZip\~ \ diff --git a/7zip/Bundles/Alone/Alone.dsp b/7zip/Bundles/Alone/Alone.dsp index 9cb637bc..bcb415a9 100755 --- a/7zip/Bundles/Alone/Alone.dsp +++ b/7zip/Bundles/Alone/Alone.dsp @@ -635,6 +635,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Compress" diff --git a/7zip/Bundles/Alone/makefile b/7zip/Bundles/Alone/makefile index f5cae4a0..f2e890bc 100755 --- a/7zip/Bundles/Alone/makefile +++ b/7zip/Bundles/Alone/makefile @@ -79,6 +79,7 @@ WIN_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveCommandLine.obj \ diff --git a/7zip/Bundles/Format7z/Format7z.dsp b/7zip/Bundles/Format7z/Format7z.dsp index 786f50e4..597f2bd7 100755 --- a/7zip/Bundles/Format7z/Format7z.dsp +++ b/7zip/Bundles/Format7z/Format7z.dsp @@ -93,11 +93,11 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Archive\7z\7z.def +SOURCE=..\..\Archive\7z\7z.ico # End Source File # Begin Source File -SOURCE=..\..\Archive\7z\7z.ico +SOURCE=..\..\Archive\Archive.def # End Source File # Begin Source File @@ -948,6 +948,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/Bundles/Format7z/makefile b/7zip/Bundles/Format7z/makefile index 2567f37b..02ce7144 100755 --- a/7zip/Bundles/Format7z/makefile +++ b/7zip/Bundles/Format7z/makefile @@ -44,6 +44,7 @@ WIN_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ diff --git a/7zip/Bundles/Format7zExtract/Format7z.dsp b/7zip/Bundles/Format7zExtract/Format7z.dsp index 82800b08..d3a7d434 100755 --- a/7zip/Bundles/Format7zExtract/Format7z.dsp +++ b/7zip/Bundles/Format7zExtract/Format7z.dsp @@ -93,11 +93,11 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File -SOURCE=..\..\Archive\7z\7z.def +SOURCE=..\..\Archive\7z\7z.ico # End Source File # Begin Source File -SOURCE=..\..\Archive\7z\7z.ico +SOURCE=..\..\Archive\Archive.def # End Source File # Begin Source File @@ -804,6 +804,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/Bundles/Format7zExtract/makefile b/7zip/Bundles/Format7zExtract/makefile index 56b9ff50..fbe77392 100755 --- a/7zip/Bundles/Format7zExtract/makefile +++ b/7zip/Bundles/Format7zExtract/makefile @@ -45,6 +45,7 @@ WIN_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ AR_COMMON_OBJS = \ $O\CoderMixer2.obj \ diff --git a/7zip/Bundles/SFXCon/SFXCon.dsp b/7zip/Bundles/SFXCon/SFXCon.dsp index 05899e39..c6859282 100755 --- a/7zip/Bundles/SFXCon/SFXCon.dsp +++ b/7zip/Bundles/SFXCon/SFXCon.dsp @@ -654,6 +654,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "UI" diff --git a/7zip/Bundles/SFXCon/makefile b/7zip/Bundles/SFXCon/makefile index 27aaabc3..3164dc39 100755 --- a/7zip/Bundles/SFXCon/makefile +++ b/7zip/Bundles/SFXCon/makefile @@ -58,6 +58,7 @@ WIN_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveExtractCallback.obj \ diff --git a/7zip/Bundles/SFXSetup/SFXSetup.dsp b/7zip/Bundles/SFXSetup/SFXSetup.dsp index 1e686014..a58feab5 100755 --- a/7zip/Bundles/SFXSetup/SFXSetup.dsp +++ b/7zip/Bundles/SFXSetup/SFXSetup.dsp @@ -567,6 +567,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "UI" diff --git a/7zip/Bundles/SFXSetup/makefile b/7zip/Bundles/SFXSetup/makefile index 85459496..1f86c42c 100755 --- a/7zip/Bundles/SFXSetup/makefile +++ b/7zip/Bundles/SFXSetup/makefile @@ -57,6 +57,7 @@ WIN_CTRL_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveOpenCallback.obj \ diff --git a/7zip/Bundles/SFXWin/SFXWin.dsp b/7zip/Bundles/SFXWin/SFXWin.dsp index f49239ba..ca9ce881 100755 --- a/7zip/Bundles/SFXWin/SFXWin.dsp +++ b/7zip/Bundles/SFXWin/SFXWin.dsp @@ -506,6 +506,14 @@ SOURCE=..\..\Common\StreamObjects.cpp SOURCE=..\..\Common\StreamObjects.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "File Manager" diff --git a/7zip/Bundles/SFXWin/makefile b/7zip/Bundles/SFXWin/makefile index 58d56e2c..af10c3fe 100755 --- a/7zip/Bundles/SFXWin/makefile +++ b/7zip/Bundles/SFXWin/makefile @@ -61,6 +61,7 @@ WIN_CTRL_OBJS = \ $O\ProgressUtils.obj \ $O\StreamBinder.obj \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveExtractCallback.obj \ diff --git a/7zip/Common/FileStreams.cpp b/7zip/Common/FileStreams.cpp index 5cdd4d6e..8a000e4e 100755 --- a/7zip/Common/FileStreams.cpp +++ b/7zip/Common/FileStreams.cpp @@ -39,7 +39,7 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) #ifdef _WIN32 UInt32 realProcessedSize; - bool result = File.Read(data, size, realProcessedSize); + bool result = File.ReadPart(data, size, realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; return ConvertBoolToHRESULT(result); @@ -54,14 +54,9 @@ STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) if(processedSize != NULL) *processedSize = (UInt32)res; return S_OK; - + #endif } - -STDMETHODIMP CInFileStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} #ifndef _WIN32_WCE STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize) @@ -95,10 +90,6 @@ STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSi #endif } -STDMETHODIMP CStdInFileStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} #endif STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, @@ -155,7 +146,7 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces #ifdef _WIN32 UInt32 realProcessedSize; - bool result = File.Write(data, size, realProcessedSize); + bool result = File.WritePart(data, size, realProcessedSize); if(processedSize != NULL) *processedSize = realProcessedSize; return ConvertBoolToHRESULT(result); @@ -174,12 +165,6 @@ STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *proces #endif } -STDMETHODIMP COutFileStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - - STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { @@ -229,7 +214,7 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro #ifdef _WIN32 UInt32 realProcessedSize; BOOL res = TRUE; - while (size > 0) + if (size > 0) { // Seems that Windows doesn't like big amounts writing to stdout. // So we limit portions by 32KB. @@ -238,8 +223,6 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro sizeTemp = size; res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), data, sizeTemp, (DWORD *)&realProcessedSize, NULL); - if (realProcessedSize == 0) - break; size -= realProcessedSize; data = (const void *)((const Byte *)data + realProcessedSize); if(processedSize != NULL) @@ -265,8 +248,4 @@ STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *pro #endif } -STDMETHODIMP CStdOutFileStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} #endif diff --git a/7zip/Common/FileStreams.h b/7zip/Common/FileStreams.h index ea79e1b9..9326372a 100755 --- a/7zip/Common/FileStreams.h +++ b/7zip/Common/FileStreams.h @@ -36,7 +36,6 @@ public: MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(GetSize)(UInt64 *size); @@ -55,7 +54,6 @@ public: virtual ~CStdInFileStream() {} STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; #endif @@ -80,7 +78,6 @@ public: MY_UNKNOWN_IMP1(IOutStream) STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(SetSize)(Int64 newSize); }; @@ -95,7 +92,6 @@ public: virtual ~CStdOutFileStream() {} STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/InBuffer.cpp b/7zip/Common/InBuffer.cpp index 8c05874b..f1d58756 100755 --- a/7zip/Common/InBuffer.cpp +++ b/7zip/Common/InBuffer.cpp @@ -59,7 +59,7 @@ bool CInBuffer::ReadBlock() return false; _processedSize += (_buffer - _bufferBase); UInt32 numProcessedBytes; - HRESULT result = _stream->ReadPart(_bufferBase, _bufferSize, &numProcessedBytes); + HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes); #ifdef _NO_EXCEPTIONS ErrorCode = result; #else @@ -71,3 +71,10 @@ bool CInBuffer::ReadBlock() _wasFinished = (numProcessedBytes == 0); return (!_wasFinished); } + +Byte CInBuffer::ReadBlock2() +{ + if(!ReadBlock()) + return 0xFF; + return *_buffer++; +} diff --git a/7zip/Common/InBuffer.h b/7zip/Common/InBuffer.h index 3d53eb51..057caa16 100755 --- a/7zip/Common/InBuffer.h +++ b/7zip/Common/InBuffer.h @@ -17,15 +17,16 @@ public: class CInBuffer { - UInt64 _processedSize; - Byte *_bufferBase; - UInt32 _bufferSize; Byte *_buffer; Byte *_bufferLimit; + Byte *_bufferBase; CMyComPtr<ISequentialInStream> _stream; + UInt64 _processedSize; + UInt32 _bufferSize; bool _wasFinished; bool ReadBlock(); + Byte ReadBlock2(); public: #ifdef _NO_EXCEPTIONS @@ -53,8 +54,7 @@ public: Byte ReadByte() { if(_buffer >= _bufferLimit) - if(!ReadBlock()) - return 0xFF; + return ReadBlock2(); return *_buffer++; } void ReadBytes(void *data, UInt32 size, UInt32 &processedSize) diff --git a/7zip/Common/InOutTempBuffer.cpp b/7zip/Common/InOutTempBuffer.cpp index d7fb79d7..d24212de 100755 --- a/7zip/Common/InOutTempBuffer.cpp +++ b/7zip/Common/InOutTempBuffer.cpp @@ -6,6 +6,8 @@ #include "../../Common/Defs.h" // #include "Windows/Defs.h" +#include "StreamUtils.h" + using namespace NWindows; using namespace NFile; using namespace NDirectory; @@ -86,34 +88,12 @@ bool CInOutTempBuffer::InitReading() return true; } -/* -bool CInOutTempBuffer::Read(void *data, UInt32 maxSize, UInt32 &processedSize) -{ - processedSize = 0; - if (_currentPositionInBuffer < _bufferPosition) - { - UInt32 sizeToRead = MyMin(_bufferPosition - _currentPositionInBuffer, maxSize); - memmove(data, _buffer + _currentPositionInBuffer, sizeToRead); - data = ((Byte *)data) + sizeToRead; - _currentPositionInBuffer += sizeToRead; - processedSize += sizeToRead; - maxSize -= sizeToRead; - } - if (maxSize == 0 || !_tmpFileCreated) - return true; - UInt32 localProcessedSize; - bool result = _inFile.Read(data, maxSize, localProcessedSize); - processedSize += localProcessedSize; - return result; -} -*/ - HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) { if (_currentPositionInBuffer < _bufferPosition) { UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer; - RINOK(stream->Write(_buffer + _currentPositionInBuffer, sizeToWrite, NULL)); + RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL)); _currentPositionInBuffer += sizeToWrite; } if (!_tmpFileCreated) @@ -121,11 +101,11 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream) while(true) { UInt32 localProcessedSize; - if (!_inFile.Read(_buffer, kTmpBufferMemorySize, localProcessedSize)) + if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize)) return E_FAIL; if (localProcessedSize == 0) return S_OK; - RINOK(stream->Write(_buffer, localProcessedSize, NULL)); + RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL)); } } @@ -141,8 +121,3 @@ STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, U *processedSize = size; return S_OK; } - -STDMETHODIMP CSequentialOutTempBufferImp::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} diff --git a/7zip/Common/InOutTempBuffer.h b/7zip/Common/InOutTempBuffer.h index 97ed56d0..3abe76ec 100755 --- a/7zip/Common/InOutTempBuffer.h +++ b/7zip/Common/InOutTempBuffer.h @@ -33,7 +33,6 @@ public: UInt64 GetDataSize() const { return _fileSize; } bool FlushWrite(); bool InitReading(); - // bool Read(void *data, UInt32 maxSize, UInt32 &processedSize); HRESULT WriteToStream(ISequentialOutStream *stream); }; @@ -51,7 +50,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/LSBFDecoder.h b/7zip/Common/LSBFDecoder.h index 0fb31a3e..1f5dcb59 100755 --- a/7zip/Common/LSBFDecoder.h +++ b/7zip/Common/LSBFDecoder.h @@ -22,7 +22,7 @@ template<class TInByte> class CBaseDecoder { protected: - UInt32 m_BitPos; + int m_BitPos; UInt32 m_Value; TInByte m_Stream; public: @@ -41,7 +41,7 @@ public: { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } UInt64 GetProcessedBitsSize() const { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); } - UInt32 GetBitPosition() const { return (m_BitPos & 7); } + int GetBitPosition() const { return (m_BitPos & 7); } void Normalize() { @@ -57,7 +57,7 @@ public: } } - UInt32 ReadBits(UInt32 numBits) + UInt32 ReadBits(int numBits) { Normalize(); UInt32 res = m_Value & ((1 << numBits) - 1); @@ -65,12 +65,12 @@ public: m_Value >>= numBits; return res; } - + bool ExtraBitsWereRead() const { if (NumExtraBytes == 0) return false; - return ((kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); + return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); } }; @@ -101,19 +101,19 @@ public: } } - UInt32 GetValue(UInt32 numBits) + UInt32 GetValue(int numBits) { Normalize(); return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); } - void MovePos(UInt32 numBits) + void MovePos(int numBits) { this->m_BitPos += numBits; m_NormalValue >>= numBits; } - UInt32 ReadBits(UInt32 numBits) + UInt32 ReadBits(int numBits) { Normalize(); UInt32 res = m_NormalValue & ( (1 << numBits) - 1); diff --git a/7zip/Common/LimitedStreams.cpp b/7zip/Common/LimitedStreams.cpp index 6de13c05..c048d49d 100755 --- a/7zip/Common/LimitedStreams.cpp +++ b/7zip/Common/LimitedStreams.cpp @@ -11,8 +11,7 @@ void CLimitedSequentialInStream::Init(ISequentialInStream *stream, UInt64 stream _size = streamSize; } -STDMETHODIMP CLimitedSequentialInStream::Read(void *data, - UInt32 size, UInt32 *processedSize) +STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) { UInt32 processedSizeReal; UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size))); @@ -22,15 +21,4 @@ STDMETHODIMP CLimitedSequentialInStream::Read(void *data, *processedSize = processedSizeReal; return result; } - -STDMETHODIMP CLimitedSequentialInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 processedSizeReal; - UInt32 sizeToRead = UInt32(MyMin(_size, UInt64(size))); - HRESULT result = _stream->ReadPart(data, sizeToRead, &processedSizeReal); - _size -= processedSizeReal; - if(processedSize != NULL) - *processedSize = processedSizeReal; - return result; -} diff --git a/7zip/Common/LimitedStreams.h b/7zip/Common/LimitedStreams.h index 02633bc6..d40be974 100755 --- a/7zip/Common/LimitedStreams.h +++ b/7zip/Common/LimitedStreams.h @@ -18,7 +18,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/LockedStream.cpp b/7zip/Common/LockedStream.cpp index 44af676d..36be1ceb 100755 --- a/7zip/Common/LockedStream.cpp +++ b/7zip/Common/LockedStream.cpp @@ -5,22 +5,13 @@ #include "LockedStream.h" HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size, - UInt32 *processedSize) -{ - NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); - RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); - return _stream->Read(data, size, processedSize); -} - -HRESULT CLockedInStream::ReadPart(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize) { NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL)); - return _stream->ReadPart(data, size, processedSize); + return _stream->Read(data, size, processedSize); } - STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize = 0; @@ -30,13 +21,3 @@ STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize = realProcessedSize; return result; } - -STDMETHODIMP CLockedSequentialInStreamImp::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize = 0; - HRESULT result = _lockedInStream->ReadPart(_pos, data, size, &realProcessedSize); - _pos += realProcessedSize; - if (processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} diff --git a/7zip/Common/LockedStream.h b/7zip/Common/LockedStream.h index 90f28330..1c1e1793 100755 --- a/7zip/Common/LockedStream.h +++ b/7zip/Common/LockedStream.h @@ -15,7 +15,6 @@ public: void Init(IInStream *stream) { _stream = stream; } HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); - HRESULT ReadPart(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize); }; class CLockedSequentialInStreamImp: @@ -34,7 +33,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/MSBFDecoder.h b/7zip/Common/MSBFDecoder.h index c21d5547..dc80c0f7 100755 --- a/7zip/Common/MSBFDecoder.h +++ b/7zip/Common/MSBFDecoder.h @@ -4,6 +4,9 @@ #ifndef __STREAM_MSBFDECODER_H #define __STREAM_MSBFDECODER_H +#include "../../Common/Types.h" +#include "../IStream.h" + namespace NStream { namespace NMSBF { @@ -16,10 +19,10 @@ const UInt32 kMask = (1 << kNumValueBits) - 1; template<class TInByte> class CDecoder { - TInByte m_Stream; UInt32 m_BitPos; UInt32 m_Value; public: + TInByte m_Stream; bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} void ReleaseStream() { m_Stream.ReleaseStream();} diff --git a/7zip/Common/OffsetStream.cpp b/7zip/Common/OffsetStream.cpp index cc93c0db..997ccae2 100755 --- a/7zip/Common/OffsetStream.cpp +++ b/7zip/Common/OffsetStream.cpp @@ -12,17 +12,11 @@ HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset) return _stream->Seek(offset, STREAM_SEEK_SET, NULL); } -STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, - UInt32 *processedSize) +STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { return _stream->Write(data, size, processedSize); } -STDMETHODIMP COffsetOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return _stream->WritePart(data, size, processedSize); -} - STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { diff --git a/7zip/Common/OffsetStream.h b/7zip/Common/OffsetStream.h index 20c65452..57a055cc 100755 --- a/7zip/Common/OffsetStream.h +++ b/7zip/Common/OffsetStream.h @@ -18,7 +18,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(SetSize)(Int64 newSize); }; diff --git a/7zip/Common/OutBuffer.cpp b/7zip/Common/OutBuffer.cpp index ab4651b4..38827de1 100755 --- a/7zip/Common/OutBuffer.cpp +++ b/7zip/Common/OutBuffer.cpp @@ -32,35 +32,78 @@ void COutBuffer::SetStream(ISequentialOutStream *stream) void COutBuffer::Init() { - _processedSize = 0; + _streamPos = 0; + _limitPos = _bufferSize; _pos = 0; + _processedSize = 0; #ifdef _NO_EXCEPTIONS ErrorCode = S_OK; #endif } -HRESULT COutBuffer::Flush() +UInt64 COutBuffer::GetProcessedSize() const +{ + UInt64 res = _processedSize + _pos - _streamPos; + if (_streamPos > _pos) + res += _bufferSize; + return res; +} + +HRESULT COutBuffer::FlushPart() { - if (_pos == 0) - return S_OK; - UInt32 processedSize; - HRESULT result = _stream->Write(_buffer, _pos, &processedSize); - if (result != S_OK) + UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos); + HRESULT result = S_OK; + #ifdef _NO_EXCEPTIONS + if (ErrorCode != S_OK) + result = ErrorCode; + #endif + if (size == 0) return result; - if (_pos != processedSize) - return E_FAIL; - _processedSize += processedSize; - _pos = 0; - return S_OK; + if (_buffer2 != 0) + { + memmove(_buffer2, _buffer + _streamPos, size); + _buffer2 += size; + } + + if (_stream != 0 + #ifdef _NO_EXCEPTIONS + && (ErrorCode != S_OK) + #endif + ) + { + UInt32 processedSize = 0; + result = _stream->Write(_buffer + _streamPos, size, &processedSize); + size = processedSize; + } + _streamPos += size; + _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize; + if (_streamPos == _bufferSize) + _streamPos = 0; + _processedSize += size; + return result; } -void COutBuffer::WriteBlock() +HRESULT COutBuffer::Flush() { #ifdef _NO_EXCEPTIONS if (ErrorCode != S_OK) - return; + return ErrorCode; #endif - HRESULT result = Flush(); + + while(_streamPos != _pos) + { + HRESULT result = FlushPart(); + if (result != S_OK) + return result; + } + return S_OK; +} + +void COutBuffer::FlushWithCheck() +{ + HRESULT result = FlushPart(); + if (_pos == _bufferSize) + _pos = 0; #ifdef _NO_EXCEPTIONS ErrorCode = result; #else diff --git a/7zip/Common/OutBuffer.h b/7zip/Common/OutBuffer.h index b161ad65..51ccb659 100755 --- a/7zip/Common/OutBuffer.h +++ b/7zip/Common/OutBuffer.h @@ -16,48 +16,40 @@ struct COutBufferException class COutBuffer { +protected: Byte *_buffer; UInt32 _pos; + UInt32 _limitPos; + UInt32 _streamPos; UInt32 _bufferSize; CMyComPtr<ISequentialOutStream> _stream; UInt64 _processedSize; + Byte *_buffer2; - void WriteBlock(); + HRESULT FlushPart(); + void FlushWithCheck(); public: #ifdef _NO_EXCEPTIONS HRESULT ErrorCode; #endif - COutBuffer(): _buffer(0), _pos(0), _stream(0) {} + COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {} ~COutBuffer() { Free(); } bool Create(UInt32 bufferSize); void Free(); + void SetMemStream(Byte *buffer) { _buffer2 = buffer; } void SetStream(ISequentialOutStream *stream); void Init(); HRESULT Flush(); void ReleaseStream() { _stream.Release(); } - /* - void *GetBuffer(UInt32 &sizeAvail) - { - sizeAvail = _bufferSize - _pos; - return _buffer + _pos; - } - void MovePos(UInt32 num) - { - _pos += num; - if(_pos >= _bufferSize) - WriteBlock(); - } - */ - void WriteByte(Byte b) { _buffer[_pos++] = b; - if(_pos >= _bufferSize) - WriteBlock(); + if(_pos == _limitPos) + FlushWithCheck(); } void WriteBytes(const void *data, size_t size) { @@ -65,7 +57,7 @@ public: WriteByte(((const Byte *)data)[i]); } - UInt64 GetProcessedSize() const { return _processedSize + _pos; } + UInt64 GetProcessedSize() const; }; #endif diff --git a/7zip/Common/StreamBinder.cpp b/7zip/Common/StreamBinder.cpp index fb4ca59f..2984c2d9 100755 --- a/7zip/Common/StreamBinder.cpp +++ b/7zip/Common/StreamBinder.cpp @@ -17,7 +17,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); private: CStreamBinder *m_StreamBinder; public: @@ -27,9 +26,6 @@ public: STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize) { return m_StreamBinder->Read(data, size, processedSize); } - -STDMETHODIMP CSequentialInStreamForBinder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) - { return m_StreamBinder->ReadPart(data, size, processedSize); } class CSequentialOutStreamForBinder: public ISequentialOutStream, @@ -39,7 +35,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); private: CStreamBinder *m_StreamBinder; @@ -51,9 +46,6 @@ public: STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) { return m_StreamBinder->Write(data, size, processedSize); } -STDMETHODIMP CSequentialOutStreamForBinder::WritePart(const void *data, UInt32 size, UInt32 *processedSize) - { return m_StreamBinder->WritePart(data, size, processedSize); } - ////////////////////////// // CStreamBinder @@ -106,7 +98,7 @@ void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ProcessedSize = 0; } -STDMETHODIMP CStreamBinder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) { UInt32 sizeToRead = size; if (size > 0) @@ -132,33 +124,12 @@ STDMETHODIMP CStreamBinder::ReadPart(void *data, UInt32 size, UInt32 *processedS return S_OK; } -STDMETHODIMP CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 fullProcessedSize = 0; - UInt32 realProcessedSize; - HRESULT result = S_OK; - while(size > 0) - { - result = ReadPart(data, size, &realProcessedSize); - size -= realProcessedSize; - data = (void *)((Byte *)data + realProcessedSize); - fullProcessedSize += realProcessedSize; - if (result != S_OK) - break; - if (realProcessedSize == 0) - break; - } - if (processedSize != NULL) - *processedSize = fullProcessedSize; - return result; -} - void CStreamBinder::CloseRead() { _readStreamIsClosedEvent->Set(); } -STDMETHODIMP CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) { if (size > 0) { @@ -184,11 +155,6 @@ STDMETHODIMP CStreamBinder::Write(const void *data, UInt32 size, UInt32 *process return S_OK; } -STDMETHODIMP CStreamBinder::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - void CStreamBinder::CloseWrite() { // _bufferSize must be = 0 diff --git a/7zip/Common/StreamBinder.h b/7zip/Common/StreamBinder.h index 588713ed..a66c3acb 100755 --- a/7zip/Common/StreamBinder.h +++ b/7zip/Common/StreamBinder.h @@ -26,12 +26,10 @@ public: void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream); - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); + HRESULT Read(void *data, UInt32 size, UInt32 *processedSize); void CloseRead(); - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); + HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize); void CloseWrite(); void ReInit(); }; diff --git a/7zip/Common/StreamObjects.cpp b/7zip/Common/StreamObjects.cpp index 8632cff4..c89f64e1 100755 --- a/7zip/Common/StreamObjects.cpp +++ b/7zip/Common/StreamObjects.cpp @@ -5,45 +5,6 @@ #include "StreamObjects.h" #include "../../Common/Defs.h" -/* -STDMETHODIMP COutStreamImp::Read(void *data, ULONG size, ULONG *processedSize) - { return E_NOTIMPL; } - -STDMETHODIMP COutStreamImp::Write(void const *data, ULONG size, ULONG *processedSize) -{ - size_t newCapacity = _size + size; - _buffer.EnsureCapacity(newCapacity); - memmove(_buffer + _size, data, size); - if(processedSize != NULL) - *processedSize = size; - _size += size; - return S_OK; -} - -void CInStreamImp::Init(Byte *dataPointer, size_t size) -{ - _dataPointer = dataPointer; - _size = size; - _pos = 0; -} - -STDMETHODIMP CInStreamImp::Read(void *data, ULONG size, ULONG *processedSize) -{ - UInt32 numBytesToRead = MyMin(_pos + (UInt32)size, _size) - _pos; - if(processedSize != NULL) - *processedSize = numBytesToRead; - memmove(data, _dataPointer + _pos, numBytesToRead); - _pos += numBytesToRead; - if(numBytesToRead == size) - return S_OK; - else - return S_FALSE; -} - -STDMETHODIMP CInStreamImp::Write(void const *data, ULONG size, ULONG *processedSize) - { return E_NOTIMPL; } -*/ - STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize) { @@ -55,13 +16,6 @@ STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *proce return S_OK; } -STDMETHODIMP CSequentialInStreamImp::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - -//////////////////// - void CWriteBuffer::Write(const void *data, size_t size) { @@ -79,11 +33,6 @@ STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt3 return S_OK; } -STDMETHODIMP CSequentialOutStreamImp::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize) { UInt32 newSize = size; @@ -98,13 +47,6 @@ STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt return S_OK; } -STDMETHODIMP CSequentialOutStreamImp2::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - - - STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; @@ -115,37 +57,8 @@ STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 return result; } -STDMETHODIMP CSequentialInStreamSizeCount::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->ReadPart(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize != 0) - *processedSize = realProcessedSize; - return result; -} - STDMETHODIMP CSequentialInStreamRollback::Read(void *data, UInt32 size, UInt32 *processedSize) { - HRESULT result = S_OK; - UInt32 realProcessedSizeTotal = 0; - while (size > 0) - { - UInt32 realProcessedSize = 0; - result = ReadPart(data, size, &realProcessedSize); - size -= realProcessedSize; - data = ((Byte *)data + realProcessedSize); - realProcessedSizeTotal += realProcessedSize; - if (realProcessedSize == 0 || result != S_OK) - break; - } - if (processedSize != 0) - *processedSize = realProcessedSizeTotal; - return result; -} - -STDMETHODIMP CSequentialInStreamRollback::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ if (_currentPos != _currentSize) { size_t curSize = _currentSize - _currentPos; @@ -160,7 +73,7 @@ STDMETHODIMP CSequentialInStreamRollback::ReadPart(void *data, UInt32 size, UInt UInt32 realProcessedSize; if (size > _bufferSize) size = (UInt32)_bufferSize; - HRESULT result = _stream->ReadPart(_buffer, size, &realProcessedSize); + HRESULT result = _stream->Read(_buffer, size, &realProcessedSize); memmove(data, _buffer, realProcessedSize); _size += realProcessedSize; _currentSize = realProcessedSize; @@ -178,7 +91,6 @@ HRESULT CSequentialInStreamRollback::Rollback(size_t rollbackSize) return S_OK; } - STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize) { UInt32 realProcessedSize; @@ -188,13 +100,3 @@ STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, *processedSize = realProcessedSize; return result; } - -STDMETHODIMP CSequentialOutStreamSizeCount::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->WritePart(data, size, &realProcessedSize); - _size += realProcessedSize; - if (processedSize != 0) - *processedSize = realProcessedSize; - return result; -} diff --git a/7zip/Common/StreamObjects.h b/7zip/Common/StreamObjects.h index 78e31980..4dd01e47 100755 --- a/7zip/Common/StreamObjects.h +++ b/7zip/Common/StreamObjects.h @@ -7,44 +7,6 @@ #include "../../Common/MyCom.h" #include "../IStream.h" -/* -class COutStreamImp: - public ISequentialStream, - public CMyUnknownImp -{ - CByteDynamicBuffer _buffer; - size_t _size; -public: - COutStreamImp(): _size(0) {} - void Init(){ _size = 0; } - size_t GetSize() const { return _size; } - const CByteDynamicBuffer& GetBuffer() const { return _buffer; } - - MY_UNKNOWN_IMP - - STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize); - STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize); -}; - -class CInStreamImp: - public ISequentialStream, - public CMyUnknownImp -{ - Byte *_dataPointer; - size_t _size; - size_t _pos; - -public: - CInStreamImp(): _size(0xFFFFFFFF), _pos(0), _dataPointer(NULL) {} - void Init(Byte *dataPointer, size_t size); - - MY_UNKNOWN_IMP - - STDMETHODIMP Read(void *data, ULONG size, ULONG *processedSize); - STDMETHODIMP Write(void const *data, ULONG size, ULONG *processedSize); -}; -*/ - class CSequentialInStreamImp: public ISequentialInStream, public CMyUnknownImp @@ -64,7 +26,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; @@ -74,15 +35,7 @@ class CWriteBuffer size_t _size; public: CWriteBuffer(): _size(0) {} - // void Init(size_t size = 0) - void Init() - { - /* - if (size > 0) - _buffer.EnsureCapacity(size); - */ - _size = 0; - } + void Init() { _size = 0; } void Write(const void *data, size_t size); size_t GetSize() const { return _size; } const CByteDynamicBuffer& GetBuffer() const { return _buffer; } @@ -94,24 +47,13 @@ class CSequentialOutStreamImp: { CWriteBuffer _writeBuffer; public: - void Init() - { - _writeBuffer.Init(); - } - - /* - void Init(size_t size = 0) - { - _writeBuffer.Init(size); - } - */ + void Init() { _writeBuffer.Init(); } size_t GetSize() const { return _writeBuffer.GetSize(); } const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); } MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; class CSequentialOutStreamImp2: @@ -133,7 +75,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; class CSequentialInStreamSizeCount: @@ -153,7 +94,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; class CSequentialInStreamRollback: @@ -191,7 +131,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); HRESULT Rollback(size_t rollbackSize); }; @@ -212,7 +151,6 @@ public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; #endif diff --git a/7zip/Common/StreamUtils.cpp b/7zip/Common/StreamUtils.cpp new file mode 100755 index 00000000..a5d9ac0e --- /dev/null +++ b/7zip/Common/StreamUtils.cpp @@ -0,0 +1,44 @@ +// StreamUtils.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" +#include "StreamUtils.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + UInt32 processedSizeLoc; + HRESULT res = stream->Read(data, size, &processedSizeLoc); + if (processedSize != 0) + *processedSize += processedSizeLoc; + data = (Byte *)((Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + return S_OK; + } + return S_OK; +} + +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize != 0) + *processedSize = 0; + while(size != 0) + { + UInt32 processedSizeLoc; + HRESULT res = stream->Write(data, size, &processedSizeLoc); + if (processedSize != 0) + *processedSize += processedSizeLoc; + data = (const void *)((const Byte *)data + processedSizeLoc); + size -= processedSizeLoc; + RINOK(res); + if (processedSizeLoc == 0) + break; + } + return S_OK; +} diff --git a/7zip/Common/StreamUtils.h b/7zip/Common/StreamUtils.h new file mode 100755 index 00000000..59f88733 --- /dev/null +++ b/7zip/Common/StreamUtils.h @@ -0,0 +1,11 @@ +// StreamUtils.h + +#ifndef __STREAMUTILS_H +#define __STREAMUTILS_H + +#include "../IStream.h" + +HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize); +HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize); + +#endif diff --git a/7zip/Compress/Arj/Decoder1.cpp b/7zip/Compress/Arj/ArjDecoder1.cpp index b9f2881c..a560f443 100755 --- a/7zip/Compress/Arj/Decoder1.cpp +++ b/7zip/Compress/Arj/ArjDecoder1.cpp @@ -2,7 +2,7 @@ #include "StdAfx.h" -#include "Decoder1.h" +#include "ArjDecoder1.h" #include "Windows/Defs.h" diff --git a/7zip/Compress/Arj/Decoder1.h b/7zip/Compress/Arj/ArjDecoder1.h index 22b1002b..22b1002b 100755 --- a/7zip/Compress/Arj/Decoder1.h +++ b/7zip/Compress/Arj/ArjDecoder1.h diff --git a/7zip/Compress/Arj/Decoder2.cpp b/7zip/Compress/Arj/ArjDecoder2.cpp index ab6c57fa..1fb20649 100755 --- a/7zip/Compress/Arj/Decoder2.cpp +++ b/7zip/Compress/Arj/ArjDecoder2.cpp @@ -2,7 +2,7 @@ #include "StdAfx.h" -#include "Decoder2.h" +#include "ArjDecoder2.h" namespace NCompress{ namespace NArj { diff --git a/7zip/Compress/Arj/Decoder2.h b/7zip/Compress/Arj/ArjDecoder2.h index bc54c1dd..bc54c1dd 100755 --- a/7zip/Compress/Arj/Decoder2.h +++ b/7zip/Compress/Arj/ArjDecoder2.h diff --git a/7zip/Compress/BZip2/BZip2CRC.cpp b/7zip/Compress/BZip2/BZip2CRC.cpp index d3ca5e15..ba9ddb7e 100755 --- a/7zip/Compress/BZip2/BZip2CRC.cpp +++ b/7zip/Compress/BZip2/BZip2CRC.cpp @@ -23,4 +23,4 @@ class CBZip2CRCTableInit { public: CBZip2CRCTableInit() { CBZip2CRC::InitTable(); } -} g_CRCTableInit; +} g_BZip2CRCTableInit; diff --git a/7zip/Compress/BZip2/BZip2Decoder.cpp b/7zip/Compress/BZip2/BZip2Decoder.cpp index e620f027..0f0fbbfa 100755 --- a/7zip/Compress/BZip2/BZip2Decoder.cpp +++ b/7zip/Compress/BZip2/BZip2Decoder.cpp @@ -174,7 +174,8 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state) } for (; i < kMaxAlphaSize; i++) lens[i] = 0; - m_HuffmanDecoders[t].SetCodeLengths(lens); + if(!m_HuffmanDecoders[t].SetCodeLengths(lens)) + return S_FALSE; } while(++t < numTables); @@ -202,7 +203,7 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state) } groupSize--; \ - int nextSym = (int)huffmanDecoder->DecodeSymbol(&m_InStream); + UInt32 nextSym = huffmanDecoder->DecodeSymbol(&m_InStream); if (nextSym < 2) { @@ -220,13 +221,18 @@ HRESULT CDecoder::ReadBlock(UInt32 blockSizeMax, CState &state) while(--runCounter != 0); runPower = 0; } - if (nextSym > numInUse) + if (nextSym <= (UInt32)numInUse) + { + Byte b = mtf.GetAndMove((int)nextSym - 1); + if (blockSize >= blockSizeMax) + return S_FALSE; + state.CharCounters[b]++; + state.tt[blockSize++] = (UInt32)b; + } + else if (nextSym == (UInt32)numInUse + 1) break; - Byte b = mtf.GetAndMove(nextSym - 1); - if (blockSize >= blockSizeMax) + else return S_FALSE; - state.CharCounters[b]++; - state.tt[blockSize++] = (UInt32)b; } } if (state.OrigPtr >= blockSize) diff --git a/7zip/Compress/Branch/x86_2.cpp b/7zip/Compress/Branch/x86_2.cpp index 2f67899f..00f1ea7a 100755 --- a/7zip/Compress/Branch/x86_2.cpp +++ b/7zip/Compress/Branch/x86_2.cpp @@ -102,7 +102,6 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, UInt32 nowPos = 0; UInt64 nowPos64 = 0; UInt32 bufferPos = 0; - UInt32 processedSize; Byte prevByte = 0; @@ -112,8 +111,18 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams, while(true) { - UInt32 size = kBufferSize - bufferPos; - RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize)); + UInt32 processedSize = 0; + while(true) + { + UInt32 size = kBufferSize - (bufferPos + processedSize); + UInt32 processedSizeLoc; + if (size == 0) + break; + RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc)); + if (processedSizeLoc == 0) + break; + processedSize += processedSizeLoc; + } UInt32 endPos = bufferPos + processedSize; if (endPos < 5) diff --git a/7zip/Compress/Copy/Copy.dsp b/7zip/Compress/Copy/Copy.dsp index ddf4d66b..099a433d 100755 --- a/7zip/Compress/Copy/Copy.dsp +++ b/7zip/Compress/Copy/Copy.dsp @@ -125,6 +125,18 @@ SOURCE=..\..\..\Common\Alloc.cpp SOURCE=..\..\..\Common\Alloc.h # End Source File # End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group # Begin Source File SOURCE=.\CopyCoder.cpp diff --git a/7zip/Compress/Copy/CopyCoder.cpp b/7zip/Compress/Copy/CopyCoder.cpp index d8c7635b..dac68711 100755 --- a/7zip/Compress/Copy/CopyCoder.cpp +++ b/7zip/Compress/Copy/CopyCoder.cpp @@ -4,6 +4,7 @@ #include "CopyCoder.h" #include "../../../Common/Alloc.h" +#include "../../Common/StreamUtils.h" namespace NCompress { @@ -34,10 +35,10 @@ STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream, if (outSize != 0) if (size > *outSize - TotalSize) size = (UInt32)(*outSize - TotalSize); - RINOK(inStream->ReadPart(_buffer, size, &realProcessedSize)); + RINOK(inStream->Read(_buffer, size, &realProcessedSize)); if(realProcessedSize == 0) break; - RINOK(outStream->Write(_buffer, realProcessedSize, NULL)); + RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL)); TotalSize += realProcessedSize; if (progress != NULL) { diff --git a/7zip/Compress/Copy/makefile b/7zip/Compress/Copy/makefile index 6c04af97..8c108fbc 100755 --- a/7zip/Compress/Copy/makefile +++ b/7zip/Compress/Copy/makefile @@ -10,10 +10,14 @@ COPY_OBJS = \ COMMON_OBJS = \ $O\Alloc.obj \ +7ZIP_COMMON_OBJS = \ + $O\StreamUtils.obj \ + OBJS = \ $O\StdAfx.obj \ $(COPY_OBJS) \ $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ $O\resource.res !include "../../../Build.mak" @@ -22,3 +26,5 @@ $(COPY_OBJS): $(*B).cpp $(COMPL) $(COMMON_OBJS): ../../../Common/$(*B).cpp $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) diff --git a/7zip/Compress/Deflate/DeflateDecoder.cpp b/7zip/Compress/Deflate/DeflateDecoder.cpp index 96da47b3..16369326 100755 --- a/7zip/Compress/Deflate/DeflateDecoder.cpp +++ b/7zip/Compress/Deflate/DeflateDecoder.cpp @@ -8,7 +8,10 @@ namespace NCompress { namespace NDeflate { namespace NDecoder { -CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode) {} +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + +CCoder::CCoder(bool deflate64Mode): _deflate64Mode(deflate64Mode), _keepHistory(false) {} void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels) { @@ -40,211 +43,256 @@ void CCoder::DeCodeLevelTable(Byte *newLevels, int numLevels) } } -void CCoder::ReadTables(void) -{ - if(m_FinalBlock) // test it - throw CException(CException::kData); +#define RIF(x) { if (!(x)) return false; } +bool CCoder::ReadTables(void) +{ m_FinalBlock = (m_InBitStream.ReadBits(kFinalBlockFieldSize) == NFinalBlockField::kFinalBlock); - int blockType = m_InBitStream.ReadBits(kBlockTypeFieldSize); + if (blockType > NBlockType::kDynamicHuffman) + return false; - switch(blockType) + if (blockType == NBlockType::kStored) { - case NBlockType::kStored: - { - m_StoredMode = true; - UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); - UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; - if (numBitsForAlign > 0) - m_InBitStream.ReadBits(numBitsForAlign); - m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize); - UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize)); - if (m_StoredBlockSize != onesComplementReverse) - throw CException(CException::kData); - break; - } - case NBlockType::kFixedHuffman: - case NBlockType::kDynamicHuffman: - { - m_StoredMode = false; - Byte litLenLevels[kStaticMainTableSize]; - Byte distLevels[kStaticDistTableSize]; - if (blockType == NBlockType::kFixedHuffman) - { - int i; - - // Leteral / length levels - for (i = 0; i < 144; i++) - litLenLevels[i] = 8; - for (; i < 256; i++) - litLenLevels[i] = 9; - for (; i < 280; i++) - litLenLevels[i] = 7; - for (; i < 288; i++) /* make a complete, but wrong code set */ - litLenLevels[i] = 8; - - // Distance levels - for (i = 0; i < kStaticDistTableSize; i++) // test it: infozip only use kDistTableSize - distLevels[i] = 5; - } - else // in case when (blockType == kDeflateBlockTypeFixedHuffman) - { - int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) + - kDeflateNumberOfLitLenCodesMin; - int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) + - kDeflateNumberOfDistanceCodesMin; - int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) + - kDeflateNumberOfLevelCodesMin; - - int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 : - kHeapTablesSizesSum32; - - Byte levelLevels[kLevelTableSize]; - int i; - for (i = 0; i < kLevelTableSize; i++) - { - int position = kCodeLengthAlphabetOrder[i]; - if(i < numLevelCodes) - levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); - else - levelLevels[position] = 0; - } - - try - { - m_LevelDecoder.SetCodeLengths(levelLevels); - } - catch(...) - { - throw CException(CException::kData); - } - - Byte tmpLevels[kStaticMaxTableSize]; - DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels); - - memmove(litLenLevels, tmpLevels, numLitLenLevels); - memset(litLenLevels + numLitLenLevels, 0, - kStaticMainTableSize - numLitLenLevels); - - memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels); - memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels); - } - try - { - m_MainDecoder.SetCodeLengths(litLenLevels); - m_DistDecoder.SetCodeLengths(distLevels); - } - catch(...) - { - throw CException(CException::kData); - } - break; - } - default: - throw CException(CException::kData); + m_StoredMode = true; + UInt32 currentBitPosition = m_InBitStream.GetBitPosition(); + UInt32 numBitsForAlign = currentBitPosition > 0 ? (8 - currentBitPosition): 0; + if (numBitsForAlign > 0) + m_InBitStream.ReadBits(numBitsForAlign); + m_StoredBlockSize = m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize); + UInt16 onesComplementReverse = ~(UInt16)(m_InBitStream.ReadBits(kDeflateStoredBlockLengthFieldSizeSize)); + return (m_StoredBlockSize == onesComplementReverse); } + + m_StoredMode = false; + Byte litLenLevels[kStaticMainTableSize]; + Byte distLevels[kStaticDistTableSize]; + if (blockType == NBlockType::kFixedHuffman) + { + int i; + + for (i = 0; i < 144; i++) + litLenLevels[i] = 8; + for (; i < 256; i++) + litLenLevels[i] = 9; + for (; i < 280; i++) + litLenLevels[i] = 7; + for (; i < 288; i++) // make a complete, but wrong code set + litLenLevels[i] = 8; + + for (i = 0; i < kStaticDistTableSize; i++) // test it: InfoZip only uses kDistTableSize + distLevels[i] = 5; + } + else // (blockType == kDynamicHuffman) + { + int numLitLenLevels = m_InBitStream.ReadBits(kDeflateNumberOfLengthCodesFieldSize) + + kDeflateNumberOfLitLenCodesMin; + int numDistLevels = m_InBitStream.ReadBits(kDeflateNumberOfDistanceCodesFieldSize) + + kDeflateNumberOfDistanceCodesMin; + int numLevelCodes = m_InBitStream.ReadBits(kDeflateNumberOfLevelCodesFieldSize) + + kDeflateNumberOfLevelCodesMin; + + int numLevels = _deflate64Mode ? kHeapTablesSizesSum64 : kHeapTablesSizesSum32; + + Byte levelLevels[kLevelTableSize]; + for (int i = 0; i < kLevelTableSize; i++) + { + int position = kCodeLengthAlphabetOrder[i]; + if(i < numLevelCodes) + levelLevels[position] = Byte(m_InBitStream.ReadBits(kDeflateLevelCodeFieldSize)); + else + levelLevels[position] = 0; + } + + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + + Byte tmpLevels[kStaticMaxTableSize]; + DeCodeLevelTable(tmpLevels, numLitLenLevels + numDistLevels); + + memmove(litLenLevels, tmpLevels, numLitLenLevels); + memset(litLenLevels + numLitLenLevels, 0, kStaticMainTableSize - numLitLenLevels); + + memmove(distLevels, tmpLevels + numLitLenLevels, numDistLevels); + memset(distLevels + numDistLevels, 0, kStaticDistTableSize - numDistLevels); + } + RIF(m_MainDecoder.SetCodeLengths(litLenLevels)); + return m_DistDecoder.SetCodeLengths(distLevels); } -HRESULT CCoder::CodeReal(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) +HRESULT CCoder::CodeSpec(UInt32 curSize) { - if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 17)) - return E_OUTOFMEMORY; - UInt64 pos = 0; - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(false); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - CCoderReleaser coderReleaser(this); + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + if (!_keepHistory) + { + if (!m_OutWindowStream.Create(_deflate64Mode ? kHistorySize64: kHistorySize32)) + return E_OUTOFMEMORY; + } + if (!m_InBitStream.Create(1 << 17)) + return E_OUTOFMEMORY; + m_OutWindowStream.Init(_keepHistory); + m_InBitStream.Init(); + m_FinalBlock = false; + _remainLen = 0; + _needReadTable = true; + } - m_FinalBlock = false; + if (curSize == 0) + return S_OK; - while(!m_FinalBlock) + while(_remainLen > 0 && curSize > 0) { - if (progress != NULL) + _remainLen--; + Byte b = m_OutWindowStream.GetByte(_rep0); + m_OutWindowStream.PutByte(b); + curSize--; + } + + while(curSize > 0) + { + if (_needReadTable) { - UInt64 packSize = m_InBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); + if (m_FinalBlock) + { + _remainLen = kLenIdFinished; + break; + } + if (!ReadTables()) + return S_FALSE; + _needReadTable = false; } - ReadTables(); + if(m_StoredMode) { - for (UInt32 i = 0; i < m_StoredBlockSize; i++) - m_OutWindowStream.PutByte(Byte(m_InBitStream.ReadBits(8))); - pos += m_StoredBlockSize; + for (; m_StoredBlockSize > 0 && curSize > 0; m_StoredBlockSize--, curSize--) + m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8)); + _needReadTable = (m_StoredBlockSize == 0); continue; } - while(true) + while(curSize > 0) { if (m_InBitStream.NumExtraBytes > 4) - throw CException(CException::kData); + return S_FALSE; UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); if (number < 256) { - if (outSize != NULL) - if (pos >= *outSize) - throw CException(CException::kData); - m_OutWindowStream.PutByte(Byte(number)); - pos++; + m_OutWindowStream.PutByte((Byte)number); + curSize--; continue; } else if (number >= kMatchNumber) { - if (outSize != NULL) - if (pos >= *outSize) - throw CException(CException::kData); number -= kMatchNumber; - - UInt32 length; - if (_deflate64Mode) - { - length = UInt32(kLenStart64[number]) + kMatchMinLen; - UInt32 numBits = kLenDirectBits64[number]; - if (numBits > 0) - length += m_InBitStream.ReadBits(numBits); - } - else + UInt32 len; { - length = UInt32(kLenStart32[number]) + kMatchMinLen; - UInt32 numBits = kLenDirectBits32[number]; - if (numBits > 0) - length += m_InBitStream.ReadBits(numBits); + int numBits; + if (_deflate64Mode) + { + len = kLenStart64[number]; + numBits = kLenDirectBits64[number]; + } + else + { + len = kLenStart32[number]; + numBits = kLenDirectBits32[number]; + } + len += kMatchMinLen + m_InBitStream.ReadBits(numBits); } - - + UInt32 locLen = len; + if (locLen > curSize) + locLen = (UInt32)curSize; number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kStaticDistTableSize) + return S_FALSE; UInt32 distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); - if (distance >= pos) - throw "data error"; - m_OutWindowStream.CopyBlock(distance, length); - pos += length; + if (!m_OutWindowStream.CopyBlock(distance, locLen)) + return S_FALSE; + curSize -= locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (int)len; + _rep0 = distance; + break; + } } else if (number == kReadTableNumber) + { + _needReadTable = true; break; + } else - throw CException(CException::kData); + return S_FALSE; } } - coderReleaser.NeedFlush = false; - return m_OutWindowStream.Flush(); + return S_OK; } -HRESULT CCoder::BaseCode(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, +HRESULT CCoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, ICompressProgressInfo *progress) { - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLZOutWindowException &e) { return e.ErrorCode; } + SetInStream(inStream); + m_OutWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CCoderReleaser flusher(this); + + const UInt64 start = m_OutWindowStream.GetProcessedSize(); + while(true) + { + UInt32 curSize = 1 << 18; + if (outSize != 0) + { + const UInt64 rem = *outSize - (m_OutWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + } + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) + { + UInt64 inSize = m_InBitStream.GetProcessedSize(); + UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + flusher.NeedFlush = false; + return Flush(); +} + + +#ifdef _NO_EXCEPTIONS + +#define DEFLATE_TRY_BEGIN +#define DEFLATE_TRY_END + +#else + +#define DEFLATE_TRY_BEGIN try { +#define DEFLATE_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLZOutWindowException &e) { return e.ErrorCode; } \ catch(...) { return S_FALSE; } + +#endif + +HRESULT CCoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + DEFLATE_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + DEFLATE_TRY_END } -HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value) +STDMETHODIMP CCoder::GetInStreamProcessedSize(UInt64 *value) { if (value == NULL) return E_INVALIDARG; @@ -252,29 +300,41 @@ HRESULT CCoder::BaseGetInStreamProcessedSize(UInt64 *value) return S_OK; } -STDMETHODIMP CCOMCoder::GetInStreamProcessedSize(UInt64 *value) +STDMETHODIMP CCoder::SetInStream(ISequentialInStream *inStream) { - return BaseGetInStreamProcessedSize(value); + m_InBitStream.SetStream(inStream); + return S_OK; } -HRESULT CCOMCoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) +STDMETHODIMP CCoder::ReleaseInStream() { - return BaseCode(inStream, outStream, inSize, outSize, progress); + m_InBitStream.ReleaseStream(); + return S_OK; } -STDMETHODIMP CCOMCoder64::GetInStreamProcessedSize(UInt64 *value) +STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize) { - return BaseGetInStreamProcessedSize(value); + _remainLen = kLenIdNeedInit; + m_OutWindowStream.Init(_keepHistory); + return S_OK; } -HRESULT CCOMCoder64::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) +#ifdef _ST_MODE + +STDMETHODIMP CCoder::Read(void *data, UInt32 size, UInt32 *processedSize) { - return BaseCode(inStream, outStream, inSize, outSize, progress); + DEFLATE_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = m_OutWindowStream.GetProcessedSize(); + m_OutWindowStream.SetMemStream((Byte *)data); + RINOK(CodeSpec(size)); + if (processedSize) + *processedSize = (UInt32)(m_OutWindowStream.GetProcessedSize() - startPos); + return Flush(); + DEFLATE_TRY_END } +#endif }}} diff --git a/7zip/Compress/Deflate/DeflateDecoder.h b/7zip/Compress/Deflate/DeflateDecoder.h index b1be0084..628af839 100755 --- a/7zip/Compress/Deflate/DeflateDecoder.h +++ b/7zip/Compress/Deflate/DeflateDecoder.h @@ -30,7 +30,15 @@ public: typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit; -class CCoder +class CCoder: + public ICompressCoder, + public ICompressGetInStreamProcessedSize, + #ifdef _ST_MODE + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif + public CMyUnknownImp { CLZOutWindow m_OutWindowStream; CInBit m_InBitStream; @@ -38,20 +46,27 @@ class CCoder NCompress::NHuffman::CDecoder<kNumHuffmanBits, kStaticDistTableSize> m_DistDecoder; NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; - bool m_FinalBlock; - bool m_StoredMode; UInt32 m_StoredBlockSize; + bool m_FinalBlock; + bool m_StoredMode; bool _deflate64Mode; + bool _keepHistory; + int _remainLen; + UInt32 _rep0; + bool _needReadTable; + void DeCodeLevelTable(Byte *newLevels, int numLevels); - void ReadTables(); + bool ReadTables(); void CCoder::ReleaseStreams() { m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); + ReleaseInStream(); } + + HRESULT Flush() { return m_OutWindowStream.Flush(); } class CCoderReleaser { CCoder *m_Coder; @@ -61,63 +76,60 @@ class CCoder ~CCoderReleaser() { if (NeedFlush) - m_Coder->m_OutWindowStream.Flush(); + m_Coder->Flush(); m_Coder->ReleaseStreams(); } }; friend class CCoderReleaser; + HRESULT CodeSpec(UInt32 curSize); public: - CCoder(bool deflate64Mode = false); + CCoder(bool deflate64Mode); + void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); - HRESULT BaseCode(ISequentialInStream *inStream, + #ifdef _ST_MODE + MY_UNKNOWN_IMP4( + ICompressGetInStreamProcessedSize, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream + ) + #else + MY_UNKNOWN_IMP1( + ICompressGetInStreamProcessedSize) + #endif + + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + // IGetInStreamProcessedSize - HRESULT BaseGetInStreamProcessedSize(UInt64 *aValue); + STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; class CCOMCoder : - public ICompressCoder, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp, public CCoder { public: - - MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - // IGetInStreamProcessedSize - STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue); - CCOMCoder(): CCoder(false) {} }; class CCOMCoder64 : - public ICompressCoder, - public ICompressGetInStreamProcessedSize, - public CMyUnknownImp, public CCoder { public: - MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) - - STDMETHOD(Code)(ISequentialInStream *inStream, - ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress); - - // IGetInStreamProcessedSize - STDMETHOD(GetInStreamProcessedSize)(UInt64 *aValue); - CCOMCoder64(): CCoder(true) {} }; diff --git a/7zip/Compress/Huffman/HuffmanDecoder.h b/7zip/Compress/Huffman/HuffmanDecoder.h index c956869e..57115197 100755 --- a/7zip/Compress/Huffman/HuffmanDecoder.h +++ b/7zip/Compress/Huffman/HuffmanDecoder.h @@ -8,86 +8,81 @@ namespace NCompress { namespace NHuffman { -class CDecoderException{}; +const int kNumTableBits = 9; -const UInt32 kValueTableBits = 9; - -template <int kNumBitsInLongestCode, UInt32 m_NumSymbols> +template <int kNumBitsMax, UInt32 m_NumSymbols> class CDecoder { - UInt32 m_Limits[kNumBitsInLongestCode + 1]; // m_Limits[i] = value limit for symbols with length = i - UInt32 m_Positions[kNumBitsInLongestCode + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i - UInt32 m_Symbols[m_NumSymbols]; // symbols: at first with len = 1 then 2, ... 15. - Byte m_Lengths[1 << kValueTableBits]; + UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i + UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i + UInt32 m_Symbols[m_NumSymbols]; + Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes. + public: - void SetCodeLengths(const Byte *codeLengths); + + bool SetCodeLengths(const Byte *codeLengths) + { + int lenCounts[kNumBitsMax + 1], tmpPositions[kNumBitsMax + 1]; + int i; + for(i = 1; i <= kNumBitsMax; i++) + lenCounts[i] = 0; + UInt32 symbol; + for (symbol = 0; symbol < m_NumSymbols; symbol++) + { + int len = codeLengths[symbol]; + if (len > kNumBitsMax) + return false; + lenCounts[len]++; + m_Symbols[symbol] = 0xFFFFFFFF; + } + lenCounts[0] = 0; + m_Positions[0] = m_Limits[0] = 0; + UInt32 startPos = 0; + UInt32 index = 0; + const UInt32 kMaxValue = (1 << kNumBitsMax); + for (i = 1; i <= kNumBitsMax; i++) + { + startPos += lenCounts[i] << (kNumBitsMax - i); + if (startPos > kMaxValue) + return false; + m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos; + m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; + tmpPositions[i] = m_Positions[i]; + if(i <= kNumTableBits) + { + UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits)); + for (; index < limit; index++) + m_Lengths[index] = (Byte)i; + } + } + for (symbol = 0; symbol < m_NumSymbols; symbol++) + { + int len = codeLengths[symbol]; + if (len != 0) + m_Symbols[tmpPositions[len]++] = symbol; + } + return true; + } + template <class TBitDecoder> UInt32 DecodeSymbol(TBitDecoder *bitStream) { - UInt32 numBits; - - UInt32 value = bitStream->GetValue(kNumBitsInLongestCode); - - if (value < m_Limits[kValueTableBits]) - numBits = m_Lengths[value >> (kNumBitsInLongestCode - kValueTableBits)]; + int numBits; + UInt32 value = bitStream->GetValue(kNumBitsMax); + if (value < m_Limits[kNumTableBits]) + numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)]; else - for (numBits = kValueTableBits + 1; numBits < kNumBitsInLongestCode; numBits++) - if (value < m_Limits[numBits]) - break; + for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++); bitStream->MovePos(numBits); UInt32 index = m_Positions[numBits] + - ((value - m_Limits[numBits - 1]) >> (kNumBitsInLongestCode - numBits)); + ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits)); if (index >= m_NumSymbols) - throw CDecoderException(); // test it + // throw CDecoderException(); // test it + return 0xFFFFFFFF; return m_Symbols[index]; } }; -template <int kNumBitsInLongestCode, UInt32 m_NumSymbols> -void CDecoder<kNumBitsInLongestCode, m_NumSymbols>::SetCodeLengths(const Byte *codeLengths) -{ - int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; - int i; - for(i = 1; i <= kNumBitsInLongestCode; i++) - lenCounts[i] = 0; - UInt32 symbol; - for (symbol = 0; symbol < m_NumSymbols; symbol++) - { - Byte codeLength = codeLengths[symbol]; - if (codeLength > kNumBitsInLongestCode) - throw CDecoderException(); - lenCounts[codeLength]++; - } - lenCounts[0] = 0; - tmpPositions[0] = m_Positions[0] = m_Limits[0] = 0; - UInt32 startPos = 0; - UInt32 index = 0; - const UInt32 kMaxValue = (1 << kNumBitsInLongestCode); - for (i = 1; i <= kNumBitsInLongestCode; i++) - { - startPos += lenCounts[i] << (kNumBitsInLongestCode - i); - if (startPos > kMaxValue) - throw CDecoderException(); - m_Limits[i] = startPos; - m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; - tmpPositions[i] = m_Positions[i]; - - if(i <= kValueTableBits) - { - UInt32 limit = (m_Limits[i] >> (kNumBitsInLongestCode - kValueTableBits)); // change it - memset(m_Lengths + index, Byte(i), limit - index); - index = limit; - } - } - - // if (startPos != kMaxValue) - // throw CDecoderException(); - - for (symbol = 0; symbol < m_NumSymbols; symbol++) - if (codeLengths[symbol] != 0) - m_Symbols[tmpPositions[codeLengths[symbol]]++] = symbol; -} - }} #endif diff --git a/7zip/Compress/Implode/ImplodeDecoder.cpp b/7zip/Compress/Implode/ImplodeDecoder.cpp index d8b5daea..b7689f62 100755 --- a/7zip/Compress/Implode/ImplodeDecoder.cpp +++ b/7zip/Compress/Implode/ImplodeDecoder.cpp @@ -74,7 +74,7 @@ void CCoder::ReleaseStreams() m_InBitStream.ReleaseStream(); } -void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, +bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, Byte *levels, int numLevelItems) { int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) + @@ -92,32 +92,26 @@ void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder, levels[currentIndex++] = level; } if (currentIndex != numLevelItems) - throw CException(CException::kData); - try - { - decoder.SetCodeLengths(levels); - } - catch(const NImplode::NHuffman::CDecoderException &) - { - throw CException(CException::kData); - } + return false; + return decoder.SetCodeLengths(levels); } -void CCoder::ReadTables(void) +bool CCoder::ReadTables(void) { if (m_LiteralsOn) { Byte literalLevels[kLiteralTableSize]; - ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize); + if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize)) + return false; } Byte lengthLevels[kLengthTableSize]; - ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize); + if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize)) + return false; Byte distanceLevels[kDistanceTableSize]; - ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); - + return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize); } class CCoderReleaser @@ -146,7 +140,8 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, m_InBitStream.Init(); CCoderReleaser coderReleaser(this); - ReadTables(); + if (!ReadTables()) + return S_FALSE; while(pos < unPackSize) { @@ -158,10 +153,13 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, if(m_InBitStream.ReadBits(1) == kMatchId) // match { UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits); - UInt32 distance = (m_DistanceDecoder.DecodeSymbol(&m_InBitStream) << - m_NumDistanceLowDirectBits) + lowDistBits; - + UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream); + if (distance >= kDistanceTableSize) + return S_FALSE; + distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits; UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream); + if (lengthSymbol >= kLengthTableSize) + return S_FALSE; UInt32 length = lengthSymbol + m_MinMatchLength; if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63 length += m_InBitStream.ReadBits(kNumAdditionalLengthBits); @@ -177,8 +175,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream, } else { - Byte b = Byte(m_LiteralsOn ? m_LiteralDecoder.DecodeSymbol(&m_InBitStream) : - m_InBitStream.ReadBits(kNumBitsInByte)); + Byte b; + if (m_LiteralsOn) + { + UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream); + if (temp >= kLiteralTableSize) + return S_FALSE; + b = (Byte)temp; + } + else + b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte); m_OutWindowStream.PutByte(b); pos++; } diff --git a/7zip/Compress/Implode/ImplodeDecoder.h b/7zip/Compress/Implode/ImplodeDecoder.h index 7dd35003..627edba4 100755 --- a/7zip/Compress/Implode/ImplodeDecoder.h +++ b/7zip/Compress/Implode/ImplodeDecoder.h @@ -32,9 +32,8 @@ class CCoder : int m_NumDistanceLowDirectBits; UInt32 m_MinMatchLength; - void ReadLevelItems(NImplode::NHuffman::CDecoder &table, - Byte *levels, int numLevelItems); - void ReadTables(); + bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems); + bool ReadTables(); void DeCodeLevelTable(Byte *newLevels, int numLevels); public: CCoder(); diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp index 15046d55..2fbb77fd 100755 --- a/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp +++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.cpp @@ -19,7 +19,7 @@ CDecoder::~CDecoder() delete []m_Symbols; } -void CDecoder::SetCodeLengths(const Byte *codeLengths) +bool CDecoder::SetCodeLengths(const Byte *codeLengths) { // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1]; int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1]; @@ -44,7 +44,7 @@ void CDecoder::SetCodeLengths(const Byte *codeLengths) { startPos += lenCounts[i] << (kNumBitsInLongestCode - i); if (startPos > kMaxValue) - throw CDecoderException(); + return false; m_Limitits[i] = startPos; m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1]; tmpPositions[i] = m_Positions[i] + lenCounts[i]; @@ -54,12 +54,13 @@ void CDecoder::SetCodeLengths(const Byte *codeLengths) // if _ZIP_MODE do not throw exception for trees containing only one node // #ifndef _ZIP_MODE if (startPos != kMaxValue) - throw CDecoderException(); + return false; // #endif for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++) if (codeLengths[symbolIndex] != 0) m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex; + return true; } UInt32 CDecoder::DecodeSymbol(CInBit *inStream) @@ -76,12 +77,12 @@ UInt32 CDecoder::DecodeSymbol(CInBit *inStream) } } if (i == 0) - throw CDecoderException(); + return 0xFFFFFFFF; inStream->MovePos(numBits); UInt32 index = m_Positions[numBits] + ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits)); if (index >= m_NumSymbols) - throw CDecoderException(); // test it + return 0xFFFFFFFF; return m_Symbols[index]; } diff --git a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h index 5a8b4e90..9f7aeca1 100755 --- a/7zip/Compress/Implode/ImplodeHuffmanDecoder.h +++ b/7zip/Compress/Implode/ImplodeHuffmanDecoder.h @@ -11,7 +11,6 @@ namespace NImplode { namespace NHuffman { const int kNumBitsInLongestCode = 16; -class CDecoderException{}; typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit; @@ -25,7 +24,7 @@ public: CDecoder(UInt32 numSymbols); ~CDecoder(); - void SetCodeLengths(const Byte *codeLengths); + bool SetCodeLengths(const Byte *codeLengths); UInt32 DecodeSymbol(CInBit *inStream); }; diff --git a/7zip/Compress/LZ/LZInWindow.cpp b/7zip/Compress/LZ/LZInWindow.cpp index a16a2c19..64928806 100755 --- a/7zip/Compress/LZ/LZInWindow.cpp +++ b/7zip/Compress/LZ/LZInWindow.cpp @@ -72,7 +72,7 @@ HRESULT CLZInWindow::ReadBlock() if(size == 0) return S_OK; UInt32 numReadBytes; - RINOK(_stream->ReadPart(_buffer + _streamPos, size, &numReadBytes)); + RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes)); if(numReadBytes == 0) { _posLimit = _streamPos; diff --git a/7zip/Compress/LZ/LZOutWindow.cpp b/7zip/Compress/LZ/LZOutWindow.cpp index 4101079b..093c9ce8 100755 --- a/7zip/Compress/LZ/LZOutWindow.cpp +++ b/7zip/Compress/LZ/LZOutWindow.cpp @@ -5,62 +5,29 @@ #include "../../../Common/Alloc.h" #include "LZOutWindow.h" -bool CLZOutWindow::Create(UInt32 windowSize) -{ - const UInt32 kMinBlockSize = 1; - if (windowSize < kMinBlockSize) - windowSize = kMinBlockSize; - if (_buffer != 0 && _windowSize == windowSize) - return true; - - // It's here to allow Solid decoding / and calling Create for RAR - _pos = 0; - _streamPos = 0; - - Free(); - _windowSize = windowSize; - _buffer = (Byte *)::BigAlloc(windowSize); - return (_buffer != 0); -} - -void CLZOutWindow::Free() -{ - ::BigFree(_buffer); - _buffer = 0; -} - -void CLZOutWindow::SetStream(ISequentialOutStream *stream) -{ - ReleaseStream(); - _stream = stream; - _stream->AddRef(); -} - void CLZOutWindow::Init(bool solid) { if(!solid) { _streamPos = 0; + _limitPos = _bufferSize; _pos = 0; + _processedSize = 0; + _overDict = false; } #ifdef _NO_EXCEPTIONS ErrorCode = S_OK; #endif } -void CLZOutWindow::ReleaseStream() +void CLZOutWindow::FlushWithCheck() { - if(_stream != 0) + HRESULT result = FlushPart(); + if (_pos == _bufferSize) { - // Flush(); // Test it - _stream->Release(); - _stream = 0; + _pos = 0; + _overDict = true; } -} - -void CLZOutWindow::FlushWithCheck() -{ - HRESULT result = Flush(); #ifdef _NO_EXCEPTIONS ErrorCode = result; #else @@ -69,27 +36,4 @@ void CLZOutWindow::FlushWithCheck() #endif } -HRESULT CLZOutWindow::Flush() -{ - UInt32 size = _pos - _streamPos; - if(size == 0) - return S_OK; - #ifdef _NO_EXCEPTIONS - if (ErrorCode != S_OK) - return ErrorCode; - #endif - if(_stream != 0) - { - UInt32 processedSize; - HRESULT result = _stream->Write(_buffer + _streamPos, size, &processedSize); - if (result != S_OK) - return result; - if (size != processedSize) - return E_FAIL; - } - if (_pos >= _windowSize) - _pos = 0; - _streamPos = _pos; - return S_OK; -} diff --git a/7zip/Compress/LZ/LZOutWindow.h b/7zip/Compress/LZ/LZOutWindow.h index 16bbc9e2..f2a182c0 100755 --- a/7zip/Compress/LZ/LZOutWindow.h +++ b/7zip/Compress/LZ/LZOutWindow.h @@ -4,6 +4,7 @@ #define __LZ_OUT_WINDOW_H #include "../../IStream.h" +#include "../../Common/OutBuffer.h" #ifndef _NO_EXCEPTIONS class CLZOutWindowException @@ -14,57 +15,47 @@ public: }; #endif -class CLZOutWindow +class CLZOutWindow: public COutBuffer { - Byte *_buffer; - UInt32 _pos; - UInt32 _windowSize; - UInt32 _streamPos; - ISequentialOutStream *_stream; + bool _overDict; void FlushWithCheck(); public: - #ifdef _NO_EXCEPTIONS - HRESULT ErrorCode; - #endif - - void Free(); - CLZOutWindow(): _buffer(0), _stream(0) {} - ~CLZOutWindow() { Free(); ReleaseStream(); } - bool Create(UInt32 windowSize); - - void SetStream(ISequentialOutStream *stream); void Init(bool solid = false); - HRESULT Flush(); - void ReleaseStream(); - void CopyBlock(UInt32 distance, UInt32 len) + // distance >= 0, len > 0, + bool CopyBlock(UInt32 distance, UInt32 len) { UInt32 pos = _pos - distance - 1; - if (pos >= _windowSize) - pos += _windowSize; - for(; len > 0; len--) + if (pos >= _bufferSize) + { + if (!_overDict) + return false; + pos += _bufferSize; + } + do { - if (pos >= _windowSize) + if (pos == _bufferSize) pos = 0; _buffer[_pos++] = _buffer[pos++]; - if (_pos >= _windowSize) + if (_pos == _limitPos) FlushWithCheck(); - // PutOneByte(GetOneByte(distance)); } + while(--len != 0); + return true; } void PutByte(Byte b) { _buffer[_pos++] = b; - if (_pos >= _windowSize) + if (_pos == _limitPos) FlushWithCheck(); } Byte GetByte(UInt32 distance) const { UInt32 pos = _pos - distance - 1; - if (pos >= _windowSize) - pos += _windowSize; + if (pos >= _bufferSize) + pos += _bufferSize; return _buffer[pos]; } }; diff --git a/7zip/Compress/LZMA/LZMA.dsp b/7zip/Compress/LZMA/LZMA.dsp index 0e9edda3..3fd32e1d 100755 --- a/7zip/Compress/LZMA/LZMA.dsp +++ b/7zip/Compress/LZMA/LZMA.dsp @@ -132,6 +132,14 @@ SOURCE=..\..\Common\OutBuffer.cpp SOURCE=..\..\Common\OutBuffer.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "RangeCoder" diff --git a/7zip/Compress/LZMA/LZMADecoder.cpp b/7zip/Compress/LZMA/LZMADecoder.cpp index 0863186b..57ab5a8d 100755 --- a/7zip/Compress/LZMA/LZMADecoder.cpp +++ b/7zip/Compress/LZMA/LZMADecoder.cpp @@ -8,6 +8,9 @@ namespace NCompress { namespace NLZMA { +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + void CDecoder::Init() { { @@ -41,11 +44,18 @@ void CDecoder::Init() _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0; } -HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) +HRESULT CDecoder::CodeSpec(UInt32 curSize) { - if (_remainLen == -1) + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize(); + if (curSize > rem) + curSize = (UInt32)rem; + } + + if (_remainLen == kLenIdFinished) return S_OK; - if (_remainLen == -2) + if (_remainLen == kLenIdNeedInit) { _rangeDecoder.Init(); Init(); @@ -54,8 +64,6 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) if (curSize == 0) return S_OK; - UInt64 nowPos64 = _nowPos64; - UInt32 rep0 = _reps[0]; UInt32 rep1 = _reps[1]; UInt32 rep2 = _reps[2]; @@ -67,12 +75,10 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) { previousByte = _outWindowStream.GetByte(rep0); _outWindowStream.PutByte(previousByte); - if (buffer) - *buffer++ = previousByte; - nowPos64++; _remainLen--; curSize--; } + UInt64 nowPos64 = _outWindowStream.GetProcessedSize(); if (nowPos64 == 0) previousByte = 0; else @@ -97,8 +103,6 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder, (UInt32)nowPos64, previousByte); _outWindowStream.PutByte(previousByte); - if (buffer) - *buffer++ = previousByte; state.UpdateChar(); curSize--; nowPos64++; @@ -108,20 +112,14 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) UInt32 len; if(_isRep[state.Index].Decode(&_rangeDecoder) == 1) { + bool readLen = true; if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0) { if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0) { - if (nowPos64 == 0) - return S_FALSE; state.UpdateShortRep(); - previousByte = _outWindowStream.GetByte(rep0); - _outWindowStream.PutByte(previousByte); - if (buffer) - *buffer++ = previousByte; - curSize--; - nowPos64++; - continue; + readLen = false; + len = 1; } } else @@ -143,8 +141,11 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) rep1 = rep0; rep0 = distance; } - len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen; - state.UpdateRep(); + if (readLen) + { + len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen; + state.UpdateRep(); + } } else { @@ -167,36 +168,22 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) rep0 += (_rangeDecoder.DecodeDirectBits( numDirectBits - kNumAlignBits) << kNumAlignBits); rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder); + if (rep0 == 0xFFFFFFFF) + { + _remainLen = kLenIdFinished; + return S_OK; + } } } else rep0 = posSlot; - if (rep0 >= nowPos64 || rep0 >= _dictionarySizeCheck) - { - if (rep0 != (UInt32)(Int32)(-1)) - return S_FALSE; - _nowPos64 = nowPos64; - _remainLen = -1; - return S_OK; - } } UInt32 locLen = len; if (len > curSize) locLen = (UInt32)curSize; - if (buffer) - { - for (UInt32 i = locLen; i != 0; i--) - { - previousByte = _outWindowStream.GetByte(rep0); - *buffer++ = previousByte; - _outWindowStream.PutByte(previousByte); - } - } - else - { - _outWindowStream.CopyBlock(rep0, locLen); - previousByte = _outWindowStream.GetByte(0); - } + if (!_outWindowStream.CopyBlock(rep0, locLen)) + return S_FALSE; + previousByte = _outWindowStream.GetByte(0); curSize -= locLen; nowPos64 += locLen; len -= locLen; @@ -215,7 +202,6 @@ HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize) } if (_rangeDecoder.Stream.WasFinished()) return S_FALSE; - _nowPos64 = nowPos64; _reps[0] = rep0; _reps[1] = rep1; _reps[2] = rep2; @@ -238,40 +224,47 @@ STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, while (true) { UInt32 curSize = 1 << 18; - if (_outSize != (UInt64)(Int64)(-1)) - if (curSize > _outSize - _nowPos64) - curSize = (UInt32)(_outSize - _nowPos64); - RINOK(CodeSpec(0, curSize)); - if (_remainLen == -1) + RINOK(CodeSpec(curSize)); + if (_remainLen == kLenIdFinished) break; if (progress != NULL) { UInt64 inSize = _rangeDecoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&inSize, &_nowPos64)); + UInt64 nowPos64 = _outWindowStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); } - if (_outSize != (UInt64)(Int64)(-1)) - if (_nowPos64 >= _outSize) + if (_outSizeDefined) + if (_outWindowStream.GetProcessedSize() >= _outSize) break; } flusher.NeedFlush = false; return Flush(); } + +#ifdef _NO_EXCEPTIONS + +#define LZMA_TRY_BEGIN +#define LZMA_TRY_END + +#else + +#define LZMA_TRY_BEGIN try { +#define LZMA_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const CLZOutWindowException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + + STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - #ifndef _NO_EXCEPTIONS - try - { - #endif - return CodeReal(inStream, outStream, inSize, outSize, progress); - #ifndef _NO_EXCEPTIONS - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLZOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } - #endif + LZMA_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + LZMA_TRY_END } STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) @@ -288,9 +281,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size UInt32 dictionarySize = 0; for (int i = 0; i < 4; i++) dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); - _dictionarySizeCheck = MyMax(dictionarySize, UInt32(1)); - UInt32 blockSize = MyMax(_dictionarySizeCheck, UInt32(1 << 12)); - if (!_outWindowStream.Create(blockSize)) + if (!_outWindowStream.Create(dictionarySize)) return E_OUTOFMEMORY; if (!_literalDecoder.Create(lp, lc)) return E_OUTOFMEMORY; @@ -319,38 +310,29 @@ STDMETHODIMP CDecoder::ReleaseInStream() STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) { - _outSize = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize; - _nowPos64 = 0; - _remainLen = -2; // -2 means need_init + if (_outSizeDefined = (outSize != NULL)) + _outSize = *outSize; + _remainLen = kLenIdNeedInit; _outWindowStream.Init(); return S_OK; } +#ifdef _ST_MODE + STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) { - #ifndef _NO_EXCEPTIONS - try - { - #endif - UInt64 startPos = _nowPos64; - if (_outSize != (UInt64)(Int64)(-1)) - if (size > _outSize - _nowPos64) - size = (UInt32)(_outSize - _nowPos64); - HRESULT res = CodeSpec((Byte *)data, size); + LZMA_TRY_BEGIN if (processedSize) - *processedSize = (UInt32)(_nowPos64 - startPos); - return res; - #ifndef _NO_EXCEPTIONS - } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLZOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } - #endif + *processedSize = 0; + const UInt64 startPos = _outWindowStream.GetProcessedSize(); + _outWindowStream.SetMemStream((Byte *)data); + RINOK(CodeSpec(size)); + if (processedSize) + *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos); + return Flush(); + LZMA_TRY_END } -STDMETHODIMP CDecoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} +#endif }} diff --git a/7zip/Compress/LZMA/LZMADecoder.h b/7zip/Compress/LZMA/LZMADecoder.h index 5cfd72ad..16e49269 100755 --- a/7zip/Compress/LZMA/LZMADecoder.h +++ b/7zip/Compress/LZMA/LZMADecoder.h @@ -145,9 +145,11 @@ public: class CDecoder: public ICompressCoder, public ICompressSetDecoderProperties2, + #ifdef _ST_MODE public ICompressSetInStream, public ICompressSetOutStreamSize, public ISequentialInStream, + #endif public CMyUnknownImp { CLZOutWindow _outWindowStream; @@ -170,26 +172,30 @@ class CDecoder: CLiteralDecoder _literalDecoder; - UInt32 _dictionarySizeCheck; - UInt32 _posStateMask; /////////////////// // State - UInt64 _outSize; - UInt64 _nowPos64; UInt32 _reps[4]; CState _state; Int32 _remainLen; // -1 means end of stream. // -2 means need Init + UInt64 _outSize; + bool _outSizeDefined; void Init(); - HRESULT CodeSpec(Byte *buffer, UInt32 size); + HRESULT CodeSpec(UInt32 size); public: + + #ifdef _ST_MODE MY_UNKNOWN_IMP4( ICompressSetDecoderProperties2, ICompressSetInStream, ICompressSetOutStreamSize, ISequentialInStream) + #else + MY_UNKNOWN_IMP1( + ICompressSetDecoderProperties2) + #endif void ReleaseStreams() { @@ -228,9 +234,12 @@ public: STDMETHOD(SetInStream)(ISequentialInStream *inStream); STDMETHOD(ReleaseInStream)(); STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); + #endif + CDecoder(): _outSizeDefined(false) {} virtual ~CDecoder() {} }; diff --git a/7zip/Compress/LZMA/LZMAEncoder.cpp b/7zip/Compress/LZMA/LZMAEncoder.cpp index 2e8cba15..447130e0 100755 --- a/7zip/Compress/LZMA/LZMAEncoder.cpp +++ b/7zip/Compress/LZMA/LZMAEncoder.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "../../../Common/Defs.h" +#include "../../Common/StreamUtils.h" #include "LZMAEncoder.h" @@ -498,7 +499,7 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits; for (int i = 0; i < 4; i++) properties[1 + i] = Byte(_dictionarySize >> (8 * i)); - return outStream->Write(properties, kPropSize, NULL); + return WriteStream(outStream, properties, kPropSize, NULL); } STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream) diff --git a/7zip/Compress/LZMA/makefile b/7zip/Compress/LZMA/makefile index 3ec9151d..14672b6a 100755 --- a/7zip/Compress/LZMA/makefile +++ b/7zip/Compress/LZMA/makefile @@ -20,6 +20,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\InBuffer.obj \ $O\OutBuffer.obj \ + $O\StreamUtils.obj \ LZ_OBJS = \ $O\LZInWindow.obj \ diff --git a/7zip/Compress/LZMA_Alone/AloneLZMA.dsp b/7zip/Compress/LZMA_Alone/AloneLZMA.dsp index 3f0efbdc..f9f3eb69 100755 --- a/7zip/Compress/LZMA_Alone/AloneLZMA.dsp +++ b/7zip/Compress/LZMA_Alone/AloneLZMA.dsp @@ -477,6 +477,14 @@ SOURCE=..\..\Common\OutBuffer.cpp SOURCE=..\..\Common\OutBuffer.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Source File diff --git a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp index d3965656..76b6d886 100755 --- a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp +++ b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -20,6 +20,7 @@ #include "../../../Common/StringToInt.h" #include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" #include "../LZMA/LZMADecoder.h" #include "../LZMA/LZMAEncoder.h" @@ -35,6 +36,8 @@ extern "C" using namespace NCommandLineParser; static const char *kCantAllocate = "Can not allocate memory"; +static const char *kReadError = "Read error"; +static const char *kWriteError = "Write error"; namespace NKey { enum Enum @@ -131,7 +134,7 @@ static bool GetNumber(const wchar_t *s, UInt32 &value) int main2(int n, const char *args[]) { - fprintf(stderr, "\nLZMA 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); + fprintf(stderr, "\nLZMA 4.27 Copyright (c) 1999-2005 Igor Pavlov 2005-08-07\n"); if (n == 1) { @@ -269,7 +272,7 @@ int main2(int n, const char *args[]) } UInt32 processedSize; - if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK) + if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK) throw "Can not read"; if ((UInt32)inSize != processedSize) throw "Read size error"; @@ -311,8 +314,8 @@ int main2(int n, const char *args[]) if (res != 0) throw "LzmaDecoder error"; } - if (outStream->Write(outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK) - throw "Can not write"; + if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK) + throw kWriteError; MyFree(outBuffer); MyFree(inBuffer); return 0; @@ -408,9 +411,9 @@ int main2(int n, const char *args[]) for (int i = 0; i < 8; i++) { Byte b = Byte(fileSize >> (8 * i)); - if (outStream->Write(&b, sizeof(b), 0) != S_OK) + if (outStream->Write(&b, 1, 0) != S_OK) { - fprintf(stderr, "Write error"); + fprintf(stderr, kWriteError); return 1; } } @@ -434,14 +437,14 @@ int main2(int n, const char *args[]) const UInt32 kPropertiesSize = 5; Byte properties[kPropertiesSize]; UInt32 processedSize; - if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK) + if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK) { - fprintf(stderr, "Read error"); + fprintf(stderr, kReadError); return 1; } if (processedSize != kPropertiesSize) { - fprintf(stderr, "Read error"); + fprintf(stderr, kReadError); return 1; } if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK) @@ -453,14 +456,14 @@ int main2(int n, const char *args[]) for (int i = 0; i < 8; i++) { Byte b; - if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK) + if (inStream->Read(&b, 1, &processedSize) != S_OK) { - fprintf(stderr, "Read error"); + fprintf(stderr, kReadError); return 1; } if (processedSize != 1) { - fprintf(stderr, "Read error"); + fprintf(stderr, kReadError); return 1; } fileSize |= ((UInt64)b) << (8 * i); diff --git a/7zip/Compress/LZMA_Alone/LzmaBench.cpp b/7zip/Compress/LZMA_Alone/LzmaBench.cpp index c491f97b..21e27849 100755 --- a/7zip/Compress/LZMA_Alone/LzmaBench.cpp +++ b/7zip/Compress/LZMA_Alone/LzmaBench.cpp @@ -148,7 +148,6 @@ public: Pos = 0; } STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) @@ -157,20 +156,13 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed if (size > remain) size = remain; for (UInt32 i = 0; i < size; i++) - { ((Byte *)data)[i] = Data[Pos + i]; - } Pos += size; if(processedSize != NULL) *processedSize = size; return S_OK; } -STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - class CBenchmarkOutStream: public ISequentialOutStream, public CMyUnknownImp @@ -193,7 +185,6 @@ public: } MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) @@ -211,11 +202,6 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p return S_OK; } -STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - class CCrcOutStream: public ISequentialOutStream, public CMyUnknownImp @@ -225,7 +211,6 @@ public: MY_UNKNOWN_IMP void Init() { CRC.Init(); } STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) @@ -236,11 +221,6 @@ STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *process return S_OK; } -STDMETHODIMP CCrcOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - static UInt64 GetTimeCount() { #ifdef _WIN32 diff --git a/7zip/Compress/LZMA_Alone/LzmaRam.cpp b/7zip/Compress/LZMA_Alone/LzmaRam.cpp index 387162b2..090d73d8 100755 --- a/7zip/Compress/LZMA_Alone/LzmaRam.cpp +++ b/7zip/Compress/LZMA_Alone/LzmaRam.cpp @@ -27,7 +27,6 @@ public: Pos = 0; } STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize) @@ -36,20 +35,13 @@ STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize) if (size > remain) size = remain; for (UInt32 i = 0; i < size; i++) - { ((Byte *)data)[i] = Data[Pos + i]; - } Pos += size; if(processedSize != NULL) *processedSize = size; return S_OK; } -STDMETHODIMP CInStreamRam::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - class COutStreamRam: public ISequentialOutStream, public CMyUnknownImp @@ -83,7 +75,6 @@ public: return S_OK; } STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize) @@ -101,11 +92,6 @@ STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *process return S_OK; } -STDMETHODIMP COutStreamRam::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - #define SZE_FAIL (1) #define SZE_OUTOFMEMORY (2) #define SZE_OUT_OVERFLOW (3) diff --git a/7zip/Compress/LZMA_Alone/makefile b/7zip/Compress/LZMA_Alone/makefile index b6f6541a..63a63ae4 100755 --- a/7zip/Compress/LZMA_Alone/makefile +++ b/7zip/Compress/LZMA_Alone/makefile @@ -41,12 +41,10 @@ COMMON_OBJS = \ $O\StringToInt.obj \ $O\Vector.obj -WIN_OBJS = \ - $O\Synchronization.obj - 7ZIP_COMMON_OBJS = \ $O\InBuffer.obj \ $O\OutBuffer.obj \ + $O\StreamUtils.obj \ LZ_OBJS = \ $O\LZInWindow.obj \ @@ -57,7 +55,6 @@ OBJS = \ $(LZMA_OBJS) \ $(LZMA_OPT_OBJS) \ $(COMMON_OBJS) \ - $(WIN_OBJS) \ $(7ZIP_COMMON_OBJS) \ $(LZ_OBJS) \ $O\LzmaRamDecode.obj \ @@ -85,8 +82,6 @@ $(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp $(COMPL_O2) $(COMMON_OBJS): ../../../Common/$(*B).cpp $(COMPL) -$(WIN_OBJS): ../../../Windows/$(*B).cpp - $(COMPL) $(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp $(COMPL) $(LZ_OBJS): ../LZ/$(*B).cpp diff --git a/7zip/Compress/LZMA_C/LzmaDecodeSize.c b/7zip/Compress/LZMA_C/LzmaDecodeSize.c index 59bfba6e..3dbdb2fd 100755 --- a/7zip/Compress/LZMA_C/LzmaDecodeSize.c +++ b/7zip/Compress/LZMA_C/LzmaDecodeSize.c @@ -2,7 +2,7 @@ LzmaDecodeSize.c LZMA Decoder (optimized for Size version) - LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10) + LZMA SDK 4.27 Copyright (c) 1999-2005 Igor Pavlov (2005-08-07) http://www.7-zip.org/ LZMA SDK is licensed under two licenses: @@ -66,17 +66,14 @@ Byte RangeDecoderReadByte(CRangeDecoder *rd) /* #define ReadByte (*rd->Buffer++) */ #define ReadByte (RangeDecoderReadByte(rd)) -void RangeDecoderInit(CRangeDecoder *rd, - #ifdef _LZMA_IN_CB - ILzmaInCallback *inCallback - #else - const Byte *stream, SizeT bufferSize +void RangeDecoderInit(CRangeDecoder *rd + #ifndef _LZMA_IN_CB + , const Byte *stream, SizeT bufferSize #endif ) { int i; #ifdef _LZMA_IN_CB - rd->InCallback = inCallback; rd->Buffer = rd->BufferLim = 0; #else rd->Buffer = stream; @@ -398,6 +395,7 @@ int LzmaDecode(CLzmaDecoderState *vs, rd.Range = vs->Range; rd.Code = vs->Code; #ifdef _LZMA_IN_CB + rd.InCallback = InCallback; rd.Buffer = vs->Buffer; rd.BufferLim = vs->BufferLim; #else @@ -432,11 +430,9 @@ int LzmaDecode(CLzmaDecoderState *vs, distanceLimit = 0; dictionaryPos = 0; dictionary[dictionarySize - 1] = 0; - RangeDecoderInit(&rd, - #ifdef _LZMA_IN_CB - InCallback - #else - inStream, inSize + RangeDecoderInit(&rd + #ifndef _LZMA_IN_CB + , inStream, inSize #endif ); #ifdef _LZMA_IN_CB @@ -486,11 +482,12 @@ int LzmaDecode(CLzmaDecoderState *vs, p[i] = kBitModelTotal >> 1; } - RangeDecoderInit(&rd, - #ifdef _LZMA_IN_CB - InCallback - #else - inStream, inSize + #ifdef _LZMA_IN_CB + rd.InCallback = InCallback; + #endif + RangeDecoderInit(&rd + #ifndef _LZMA_IN_CB + , inStream, inSize #endif ); diff --git a/7zip/Compress/LZMA_C/LzmaTest.c b/7zip/Compress/LZMA_C/LzmaTest.c index b4ca5422..f95a753b 100755 --- a/7zip/Compress/LZMA_C/LzmaTest.c +++ b/7zip/Compress/LZMA_C/LzmaTest.c @@ -3,7 +3,7 @@ LzmaTest.c Test application for LZMA Decoder This file written and distributed to public domain by Igor Pavlov. -This file is part of LZMA SDK 4.26 (2005-08-02) +This file is part of LZMA SDK 4.26 (2005-08-05) */ #include <stdio.h> @@ -173,12 +173,12 @@ int main3(FILE *inFile, FILE *outFile, char *rs) if (state.Probs == 0 #ifdef _LZMA_OUT_READ - || state.Dictionary == 0 && state.Properties.DictionarySize != 0 + || (state.Dictionary == 0 && state.Properties.DictionarySize != 0) #else - || outStream == 0 && outSizeFull != 0 + || (outStream == 0 && outSizeFull != 0) #endif #ifndef _LZMA_IN_CB - || inStream == 0 && compressedSize != 0 + || (inStream == 0 && compressedSize != 0) #endif ) { @@ -307,7 +307,7 @@ int main2(int numArgs, const char *args[], char *rs) FILE *outFile = 0; int res; - sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n"); + sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n"); if (numArgs < 2 || numArgs > 3) { sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n"); diff --git a/7zip/Compress/Lzx/Lzx.h b/7zip/Compress/Lzx/Lzx.h new file mode 100755 index 00000000..386a17c3 --- /dev/null +++ b/7zip/Compress/Lzx/Lzx.h @@ -0,0 +1,61 @@ +// Lzx.h + +#ifndef __COMPRESS_LZX_H +#define __COMPRESS_LZX_H + +namespace NCompress { +namespace NLzx { + +const int kNumHuffmanBits = 16; +const UInt32 kNumRepDistances = 3; + +const UInt32 kNumLenSlots = 8; +const UInt32 kMatchMinLen = 2; +const UInt32 kNumLenSymbols = 249; +const UInt32 kMatchMaxLen = kMatchMinLen + (kNumLenSlots - 1) + kNumLenSymbols - 1; + +const int kNumAlignBits = 3; +const UInt32 kAlignTableSize = 1 << kNumAlignBits; + +const UInt32 kNumPosSlots = 50; +const UInt32 kNumPosLenSlots = kNumPosSlots * kNumLenSlots; + +const UInt32 kMainTableSize = 256 + kNumPosLenSlots; +const UInt32 kLevelTableSize = 20; +const UInt32 kMaxTableSize = kMainTableSize; + +const int kNumBlockTypeBits = 3; +const int kBlockTypeVerbatim = 1; +const int kBlockTypeAligned = 2; +const int kBlockTypeUncompressed = 3; + +const int kUncompressedBlockSizeNumBits = 24; + +const int kNumBitsForPreTreeLevel = 4; + +const int kLevelSymbolZeros = 17; +const int kLevelSymbolZerosBig = 18; +const int kLevelSymbolSame = 19; + +const int kLevelSymbolZerosStartValue = 4; +const int kLevelSymbolZerosNumBits = 4; + +const int kLevelSymbolZerosBigStartValue = kLevelSymbolZerosStartValue + + (1 << kLevelSymbolZerosNumBits); +const int kLevelSymbolZerosBigNumBits = 5; + +const int kLevelSymbolSameNumBits = 1; +const int kLevelSymbolSameStartValue = 4; + +const int kNumBitsForAlignLevel = 3; + +const int kNumDictionaryBitsMin = 15; +const int kNumDictionaryBitsMax = 21; +const UInt32 kDictionarySizeMax = (1 << kNumDictionaryBitsMax); + +const int kNumLinearPosSlotBits = 17; +const UInt32 kNumPowerPosSlots = 0x26; + +}} + +#endif diff --git a/7zip/Archive/Cab/LZXi86Converter.cpp b/7zip/Compress/Lzx/Lzx86Converter.cpp index ec70a211..1265dba0 100755 --- a/7zip/Archive/Cab/LZXi86Converter.cpp +++ b/7zip/Compress/Lzx/Lzx86Converter.cpp @@ -1,62 +1,54 @@ -// Archive/Cab/LZXi86Converter.cpp +// Lzx86Converter.cpp #include "StdAfx.h" #include "Common/Defs.h" -#include "LZXi86Converter.h" +#include "Lzx86Converter.h" -namespace NArchive { -namespace NCab { -namespace NLZX { +namespace NCompress { +namespace NLzx { static const int kResidue = 6 + 4; -void Ci86TranslationOutStream::MakeTranslation() +void Cx86ConvertOutStream::MakeTranslation() { if (m_Pos <= kResidue) return; UInt32 numBytes = m_Pos - kResidue; + Byte *buffer = m_Buffer; for (UInt32 i = 0; i < numBytes;) { - if (m_Buffer[i] == 0xE8) + if (buffer[i++] == 0xE8) { - i++; Int32 absValue = 0; int j; for(j = 0; j < 4; j++) - absValue += UInt32(m_Buffer[i + j]) << (j * 8); - - Int32 pos = m_ProcessedSize + i - 1; - UInt32 offset; - if (absValue < -pos || absValue >= Int32(m_TranslationSize)) - { - } - else + absValue += (UInt32)buffer[i + j] << (j * 8); + Int32 pos = (Int32)(m_ProcessedSize + i - 1); + if (absValue >= -pos && absValue < (Int32)m_TranslationSize) { - offset = (absValue >= 0) ? + UInt32 offset = (absValue >= 0) ? absValue - pos : absValue + m_TranslationSize; for(j = 0; j < 4; j++) { - m_Buffer[i + j] = Byte(offset & 0xFF); + buffer[i + j] = (Byte)(offset & 0xFF); offset >>= 8; } } i += 4; } - else - i++; } } -STDMETHODIMP Ci86TranslationOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +STDMETHODIMP Cx86ConvertOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { + if (processedSize != NULL) + *processedSize = 0; if (!m_TranslationMode) return m_Stream->Write(data, size, processedSize); - UInt32 realProcessedSize = 0; - while (realProcessedSize < size) { UInt32 writeSize = MyMin(size - realProcessedSize, kUncompressedBlockSize - m_Pos); @@ -73,21 +65,26 @@ STDMETHODIMP Ci86TranslationOutStream::Write(const void *data, UInt32 size, UInt return S_OK; } -STDMETHODIMP Ci86TranslationOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - -HRESULT Ci86TranslationOutStream::Flush() +HRESULT Cx86ConvertOutStream::Flush() { if (m_Pos == 0) return S_OK; - MakeTranslation(); - RINOK(m_Stream->Write(m_Buffer, m_Pos, NULL)); + if (m_TranslationMode) + MakeTranslation(); + UInt32 pos = 0; + do + { + UInt32 processed; + RINOK(m_Stream->Write(m_Buffer + pos, m_Pos - pos, &processed)); + if (processed == 0) + return E_FAIL; + pos += processed; + } + while(pos < m_Pos); m_ProcessedSize += m_Pos; m_Pos = 0; - m_TranslationMode = (m_ProcessedSize < (1 << 30)); + m_TranslationMode = (m_TranslationMode && (m_ProcessedSize < (1 << 30))); return S_OK; } -}}} +}} diff --git a/7zip/Archive/Cab/LZXi86Converter.h b/7zip/Compress/Lzx/Lzx86Converter.h index 625fa506..b507a612 100755 --- a/7zip/Archive/Cab/LZXi86Converter.h +++ b/7zip/Compress/Lzx/Lzx86Converter.h @@ -1,50 +1,45 @@ -// Archive/Cab/LZXi86Converter.h +// Lzx/x86Converter.h -#ifndef __ARCHIVE_CAB_LZXI86CONVERTER_H -#define __ARCHIVE_CAB_LZXI86CONVERTER_H +#ifndef __LZX_X86CONVERTER_H +#define __LZX_X86CONVERTER_H #include "Common/MyCom.h" #include "../../IStream.h" -namespace NArchive { -namespace NCab { -namespace NLZX { +namespace NCompress { +namespace NLzx { const int kUncompressedBlockSize = 1 << 15; -class Ci86TranslationOutStream: +class Cx86ConvertOutStream: public ISequentialOutStream, public CMyUnknownImp { - bool m_TranslationMode; CMyComPtr<ISequentialOutStream> m_Stream; UInt32 m_ProcessedSize; - Byte m_Buffer[kUncompressedBlockSize]; UInt32 m_Pos; UInt32 m_TranslationSize; + bool m_TranslationMode; + Byte m_Buffer[kUncompressedBlockSize]; void MakeTranslation(); public: - Ci86TranslationOutStream(): m_Pos(0) {} - ~Ci86TranslationOutStream() { Flush(); } - - MY_UNKNOWN_IMP - - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); -public: - void Init(ISequentialOutStream *outStream, bool translationMode, UInt32 translationSize) + void SetStream(ISequentialOutStream *outStream) { m_Stream = outStream; } + void ReleaseStream() { m_Stream.Release(); } + void Init(bool translationMode, UInt32 translationSize) { - m_Stream = outStream; m_TranslationMode = translationMode; m_TranslationSize = translationSize; m_ProcessedSize = 0; m_Pos = 0; } - void ReleaseStream() { m_Stream.Release(); } HRESULT Flush(); + + MY_UNKNOWN_IMP + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); }; -}}} +}} #endif diff --git a/7zip/Compress/Lzx/LzxDecoder.cpp b/7zip/Compress/Lzx/LzxDecoder.cpp new file mode 100755 index 00000000..341e47c0 --- /dev/null +++ b/7zip/Compress/Lzx/LzxDecoder.cpp @@ -0,0 +1,382 @@ +// LzxDecoder.cpp + +#include "StdAfx.h" + +#include "LzxDecoder.h" + +#include "Common/Defs.h" +#include "Common/Alloc.h" +#include "Windows/Defs.h" + +namespace NCompress { +namespace NLzx { + +const int kLenIdNeedInit = -2; + +CDecoder::CDecoder(): + _keepHistory(false), + m_AlignPos(0) +{ + m_x86ConvertOutStreamSpec = new Cx86ConvertOutStream; + m_x86ConvertOutStream = m_x86ConvertOutStreamSpec; +} + +void CDecoder::ReleaseStreams() +{ + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + m_x86ConvertOutStreamSpec->ReleaseStream(); +} + +STDMETHODIMP CDecoder::Flush() +{ + RINOK(m_OutWindowStream.Flush()); + return m_x86ConvertOutStreamSpec->Flush(); +} + +UInt32 CDecoder::ReadBits(UInt32 numBits) { return m_InBitStream.ReadBits(numBits); } + +#define RIF(x) { if (!(x)) return false; } + +bool CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols) +{ + Byte levelLevels[kLevelTableSize]; + UInt32 i; + for (i = 0; i < kLevelTableSize; i++) + levelLevels[i] = (Byte)ReadBits(kNumBitsForPreTreeLevel); + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + int num = 0; + Byte symbol = 0; + for (i = 0; i < numSymbols;) + { + if (num != 0) + { + lastLevels[i] = newLevels[i] = symbol; + i++; + num--; + continue; + } + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number == kLevelSymbolZeros) + { + num = kLevelSymbolZerosStartValue + ReadBits(kLevelSymbolZerosNumBits); + symbol = 0; + } + else if (number == kLevelSymbolZerosBig) + { + num = kLevelSymbolZerosBigStartValue + ReadBits(kLevelSymbolZerosBigNumBits); + symbol = 0; + } + else if (number == kLevelSymbolSame || number <= kNumHuffmanBits) + { + if (number <= kNumHuffmanBits) + num = 1; + else + { + num = kLevelSymbolSameStartValue + ReadBits(kLevelSymbolSameNumBits); + number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number > kNumHuffmanBits) + return false; + } + symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); + } + else + return false; + } + return true; +} + +bool CDecoder::ReadTables(void) +{ + Byte newLevels[kMaxTableSize]; + { + int blockType = (int)ReadBits(kNumBlockTypeBits); + if (blockType > kBlockTypeUncompressed) + return false; + m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits); + + if (m_IsUncompressedBlock = (blockType == kBlockTypeUncompressed)) + { + m_InBitStream.ReadBits(16 - m_InBitStream.GetBitPosition()); + if (!m_InBitStream.ReadUInt32(m_RepDistances[0])) + return false; + m_RepDistances[0]--; + for (int i = 1; i < kNumRepDistances; i++) + { + UInt32 rep = 0; + for (int j = 0; j < 4; j++) + rep |= (UInt32)m_InBitStream.DirectReadByte() << (8 * j); + m_RepDistances[i] = rep - 1; + } + return true; + } + if (m_AlignIsUsed = (blockType == kBlockTypeAligned)) + { + for(int i = 0; i < kAlignTableSize; i++) + newLevels[i] = ReadBits(kNumBitsForAlignLevel); + RIF(m_AlignDecoder.SetCodeLengths(newLevels)); + } + } + + RIF(ReadTable(m_LastMainLevels, newLevels, 256)); + RIF(ReadTable(m_LastMainLevels + 256, newLevels + 256, m_NumPosLenSlots)); + for (UInt32 i = 256 + m_NumPosLenSlots; i < kMainTableSize; i++) + newLevels[i] = 0; + RIF(m_MainDecoder.SetCodeLengths(newLevels)); + + RIF(ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols)); + return m_LenDecoder.SetCodeLengths(newLevels); +} + +class CDecoderFlusher +{ + CDecoder *m_Decoder; +public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + m_Decoder->Flush(); + m_Decoder->ReleaseStreams(); + } +}; + + +void CDecoder::ClearPrevLevels() +{ + int i; + for (i = 0; i < kMainTableSize; i++) + m_LastMainLevels[i] = 0; + for (i = 0; i < kNumLenSymbols; i++) + m_LastLenLevels[i] = 0; +}; + + +HRESULT CDecoder::CodeSpec(UInt32 curSize) +{ + if (_remainLen == kLenIdNeedInit) + { + _remainLen = 0; + if (_keepHistory && m_IsUncompressedBlock && m_UnCompressedBlockSize > 0) + m_InBitStream.InitDirect(); + else + m_InBitStream.InitNormal(); + if (!_keepHistory) + { + m_UnCompressedBlockSize = 0; + ClearPrevLevels(); + UInt32 i86TranslationSize = 0; + bool translationMode = (ReadBits(1) != 0); + if (translationMode) + { + i86TranslationSize = ReadBits(16) << 16; + i86TranslationSize |= ReadBits(16); + } + m_x86ConvertOutStreamSpec->Init(translationMode, i86TranslationSize); + + for(int i = 0 ; i < kNumRepDistances; i++) + m_RepDistances[i] = 0; + } + } + + if (curSize == 0) + return S_OK; + + while(_remainLen > 0 && curSize > 0) + { + m_OutWindowStream.PutByte(m_OutWindowStream.GetByte(m_RepDistances[0])); + _remainLen--; + curSize--; + } + + while(curSize > 0) + { + if (m_UnCompressedBlockSize == 0) + if (!ReadTables()) + return S_FALSE; + UInt32 nowPos = 0; + UInt32 next = (Int32)MyMin(m_UnCompressedBlockSize, curSize); + curSize -= next; + m_UnCompressedBlockSize -= next; + if (m_IsUncompressedBlock) + { + while(next > 0) + { + m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte()); + next--; + } + if (m_UnCompressedBlockSize == 0) + { + m_InBitStream.Align(m_AlignPos); + m_AlignPos = 0; + } + } + else while(next > 0) + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number < 256) + { + m_OutWindowStream.PutByte((Byte)number); + next--; + } + else + { + UInt32 posLenSlot = number - 256; + if (posLenSlot >= m_NumPosLenSlots) + return S_FALSE; + UInt32 posSlot = posLenSlot / kNumLenSlots; + UInt32 lenSlot = posLenSlot % kNumLenSlots; + UInt32 len = kMatchMinLen + lenSlot; + if (lenSlot == kNumLenSlots - 1) + { + UInt32 lenTemp = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (lenTemp >= kNumLenSymbols) + return S_FALSE; + len += lenTemp; + } + + if (posSlot < kNumRepDistances) + { + UInt32 distance = m_RepDistances[posSlot]; + m_RepDistances[posSlot] = m_RepDistances[0]; + m_RepDistances[0] = distance; + } + else + { + UInt32 distance; + int numDirectBits; + if (posSlot < kNumPowerPosSlots) + { + numDirectBits = (posSlot >> 1) - 1; + distance = ((2 | (posSlot & 1)) << numDirectBits); + } + else + { + numDirectBits = kNumLinearPosSlotBits; + distance = ((posSlot - 0x22) << kNumLinearPosSlotBits); + } + + if (m_AlignIsUsed && numDirectBits >= kNumAlignBits) + { + distance += (m_InBitStream.ReadBits(numDirectBits - kNumAlignBits) << kNumAlignBits); + UInt32 alignTemp = m_AlignDecoder.DecodeSymbol(&m_InBitStream); + if (alignTemp >= kAlignTableSize) + return S_FALSE; + distance += alignTemp; + } + else + distance += m_InBitStream.ReadBits(numDirectBits); + m_RepDistances[2] = m_RepDistances[1]; + m_RepDistances[1] = m_RepDistances[0]; + m_RepDistances[0] = distance - kNumRepDistances; + } + + UInt32 locLen = len; + if (locLen > next) + locLen = next; + + if (!m_OutWindowStream.CopyBlock(m_RepDistances[0], locLen)) + return S_FALSE; + + len -= locLen; + next -= locLen; + if (len != 0) + { + _remainLen = len; + return S_OK; + } + } + } + } + return S_OK; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + UInt64 size = *outSize; + const UInt64 startSize = size; + + RINOK(SetInStream(inStream)); + m_x86ConvertOutStreamSpec->SetStream(outStream); + m_OutWindowStream.SetStream(m_x86ConvertOutStream); + RINOK(SetOutStreamSize(outSize)); + + CDecoderFlusher flusher(this); + + const UInt64 start = m_OutWindowStream.GetProcessedSize(); + while(true) + { + UInt32 curSize = 1 << 18; + UInt64 rem = size - (m_OutWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (progress != NULL) + { + UInt64 inSize = m_InBitStream.GetProcessedSize(); + UInt64 nowPos64 = m_OutWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + flusher.NeedFlush = false; + return Flush(); +} + +HRESULT CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + m_InBitStream.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + m_InBitStream.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + if (outSize == NULL) + return E_FAIL; + _remainLen = kLenIdNeedInit; + m_OutWindowStream.Init(_keepHistory); + return S_OK; +} + +HRESULT CDecoder::SetParams(int numDictBits) +{ + if (numDictBits < kNumDictionaryBitsMin || numDictBits > kNumDictionaryBitsMax) + return E_INVALIDARG; + UInt32 numPosSlots; + if (numDictBits < 20) + numPosSlots = 30 + (numDictBits - 15) * 2; + else if (numDictBits == 20) + numPosSlots = 42; + else + numPosSlots = 50; + m_NumPosLenSlots = numPosSlots * kNumLenSlots; + if (!m_OutWindowStream.Create(kDictionarySizeMax)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 16)) + return E_OUTOFMEMORY; + return S_OK; +} + +}} diff --git a/7zip/Compress/Lzx/LzxDecoder.h b/7zip/Compress/Lzx/LzxDecoder.h new file mode 100755 index 00000000..a62662ec --- /dev/null +++ b/7zip/Compress/Lzx/LzxDecoder.h @@ -0,0 +1,181 @@ +// LzxDecoder.h + +#ifndef __LZXDECODER_H +#define __LZXDECODER_H + +#include "../../ICoder.h" + +#include "../../Compress/Huffman/HuffmanDecoder.h" +#include "../../Compress/LZ/LZOutWindow.h" +#include "../../Common/InBuffer.h" + +#include "Lzx.h" +#include "Lzx86Converter.h" + +namespace NCompress { +namespace NLzx { + +namespace NBitStream { + +const int kNumBigValueBits = 8 * 4; +const int kNumValueBits = 17; +const UInt32 kBitDecoderValueMask = (1 << kNumValueBits) - 1; + +class CDecoder +{ + CInBuffer m_Stream; + UInt32 m_Value; + int m_BitPos; +public: + CDecoder() {} + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + + void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); } + void ReleaseStream() { m_Stream.ReleaseStream(); } + + void InitNormal() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + Normalize(); + } + + void InitDirect() + { + m_Stream.Init(); + m_BitPos = kNumBigValueBits; + } + + UInt64 GetProcessedSize() const + { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } + + int GetBitPosition() const { return m_BitPos & 0xF; } + + void Normalize() + { + for (;m_BitPos >= 16; m_BitPos -= 16) + { + Byte b0 = m_Stream.ReadByte(); + Byte b1 = m_Stream.ReadByte(); + m_Value = (m_Value << 8) | b1; + m_Value = (m_Value << 8) | b0; + } + } + + UInt32 GetValue(int numBits) const + { + return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> + (kNumValueBits - numBits); + } + + void MovePos(UInt32 numBits) + { + m_BitPos += numBits; + Normalize(); + } + + UInt32 ReadBits(int numBits) + { + UInt32 res = GetValue(numBits); + MovePos(numBits); + return res; + } + + UInt32 ReadBitsBig(int numBits) + { + UInt32 numBits0 = numBits / 2; + UInt32 numBits1 = numBits - numBits0; + UInt32 res = ReadBits(numBits0) << numBits1; + return res + ReadBits(numBits1); + } + + bool ReadUInt32(UInt32 &v) + { + if (m_BitPos != 0) + return false; + v = ((m_Value >> 16) & 0xFFFF) | ((m_Value << 16) & 0xFFFF0000); + m_BitPos = kNumBigValueBits; + return true; + } + + Byte DirectReadByte() { return m_Stream.ReadByte(); } + + void Align(int alignPos) + { + if (((m_Stream.GetProcessedSize() + alignPos) & 1) != 0) + m_Stream.ReadByte(); + Normalize(); + } +}; +} + +class CDecoder : + public ICompressCoder, + public CMyUnknownImp +{ + NBitStream::CDecoder m_InBitStream; + CLZOutWindow m_OutWindowStream; + + UInt32 m_RepDistances[kNumRepDistances]; + UInt32 m_NumPosLenSlots; + + bool m_IsUncompressedBlock; + bool m_AlignIsUsed; + + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder; + NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; + + Byte m_LastMainLevels[kMainTableSize]; + Byte m_LastLenLevels[kNumLenSymbols]; + + Cx86ConvertOutStream *m_x86ConvertOutStreamSpec; + CMyComPtr<ISequentialOutStream> m_x86ConvertOutStream; + + UInt32 m_UnCompressedBlockSize; + + bool _keepHistory; + int _remainLen; + int m_AlignPos; + + UInt32 ReadBits(UInt32 numBits); + bool ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols); + bool ReadTables(); + void ClearPrevLevels(); + + HRESULT CodeSpec(UInt32 size); + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); +public: + CDecoder(); + + MY_UNKNOWN_IMP + + void ReleaseStreams(); + STDMETHOD(Flush)(); + + // ICompressCoder interface + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + HRESULT SetParams(int numDictBits); + void SetKeepHistory(bool keepHistory, int alignPos) + { + _keepHistory = keepHistory; + m_AlignPos = alignPos; + } +}; + +}} + +#endif diff --git a/7zip/Compress/Lzx/StdAfx.h b/7zip/Compress/Lzx/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/Lzx/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/PPMD/PPMD.dsp b/7zip/Compress/PPMD/PPMD.dsp index 09c3d7f8..9e512f6c 100755 --- a/7zip/Compress/PPMD/PPMD.dsp +++ b/7zip/Compress/PPMD/PPMD.dsp @@ -192,6 +192,14 @@ SOURCE=..\..\Common\OutBuffer.cpp SOURCE=..\..\Common\OutBuffer.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "RangeCoder" diff --git a/7zip/Compress/PPMD/PPMDContext.h b/7zip/Compress/PPMD/PPMDContext.h index 1b926585..6f154fc4 100755 --- a/7zip/Compress/PPMD/PPMDContext.h +++ b/7zip/Compress/PPMD/PPMDContext.h @@ -15,9 +15,9 @@ namespace NPPMD { const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; -#pragma pack(1) struct SEE2_CONTEXT -{ // SEE-contexts for PPM-contexts with masked symbols +{ + // SEE-contexts for PPM-contexts with masked symbols UInt16 Summ; Byte Shift, Count; void init(int InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=4; } @@ -39,9 +39,25 @@ struct SEE2_CONTEXT struct PPM_CONTEXT { - UInt16 NumStats,SummFreq; // sizeof(UInt16) > sizeof(Byte) - struct STATE { Byte Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats; - PPM_CONTEXT* Suffix; + UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte) + UInt16 SummFreq; + + struct STATE + { + Byte Symbol, Freq; + UInt16 SuccessorLow; + UInt16 SuccessorHigh; + + UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); } + void SetSuccessor(UInt32 v) + { + SuccessorLow = (UInt16)(v & 0xFFFF); + SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF); + } + }; + + UInt32 Stats; + UInt32 Suffix; PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState) { @@ -50,15 +66,14 @@ struct PPM_CONTEXT { pc->NumStats = 1; pc->oneState() = FirstState; - pc->Suffix = this; - pStats->Successor = pc; + pc->Suffix = subAllocator.GetOffset(this); + pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc)); } return pc; } STATE& oneState() const { return (STATE&) SummFreq; } }; -#pragma pack() ///////////////////////////////// @@ -68,8 +83,8 @@ const UInt16 InitBinEsc[] = struct CInfo { CSubAllocator SubAllocator; - SEE2_CONTEXT _PACK_ATTR SEE2Cont[25][16], DummySEE2Cont; - PPM_CONTEXT _PACK_ATTR * MinContext, * MaxContext; + SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; + PPM_CONTEXT * MinContext, * MaxContext; PPM_CONTEXT::STATE* FoundState; // found next state transition int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder; @@ -86,6 +101,11 @@ struct CInfo ((RunLength >> 26) & 0x20)]; } + PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); } + PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + void RestartModelRare() { int i, k, m; @@ -93,15 +113,17 @@ struct CInfo SubAllocator.InitSubAllocator(); InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1; MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext(); - MinContext->Suffix = NULL; + MinContext->Suffix = 0; OrderFall = MaxOrder; MinContext->SummFreq = (MinContext->NumStats = 256) + 1; - FoundState = MinContext->Stats = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(256 / 2); + FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2); + MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState); for (RunLength = InitRL, PrevSuccess = i = 0; i < 256; i++) { - MinContext->Stats[i].Symbol = i; - MinContext->Stats[i].Freq = 1; - MinContext->Stats[i].Successor = NULL; + PPM_CONTEXT::STATE &state = FoundState[i]; + state.Symbol = i; + state.Freq = 1; + state.SetSuccessor(0); } for (i = 0; i < 128; i++) for (k = 0; k < 8; k++) @@ -121,12 +143,12 @@ struct CInfo memset(CharMask,0,sizeof(CharMask)); OrderFall = this->MaxOrder; MinContext = MaxContext; - while (MinContext->Suffix != NULL) + while (MinContext->Suffix != 0) { - MinContext = MinContext->Suffix; - OrderFall--; + MinContext = GetContextNoCheck(MinContext->Suffix); + OrderFall--; } - FoundState = MinContext->Stats; + FoundState = GetState(MinContext->Stats); MinContext = MaxContext; } else @@ -160,7 +182,8 @@ struct CInfo // static PPM_CONTEXT::STATE UpState; PPM_CONTEXT::STATE UpState; - PPM_CONTEXT* pc = MinContext, * UpBranch = FoundState->Successor; + PPM_CONTEXT *pc = MinContext; + PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor()); PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps; if ( !skip ) { @@ -171,23 +194,23 @@ struct CInfo if ( p1 ) { p = p1; - pc = pc->Suffix; + pc = GetContext(pc->Suffix); goto LOOP_ENTRY; } do { - pc = pc->Suffix; + pc = GetContext(pc->Suffix); if (pc->NumStats != 1) { - if ((p = pc->Stats)->Symbol != FoundState->Symbol) + if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol) do { p++; } while (p->Symbol != FoundState->Symbol); } else p = &(pc->oneState()); LOOP_ENTRY: - if (p->Successor != UpBranch) + if (GetContext(p->GetSuccessor()) != UpBranch) { - pc = p->Successor; + pc = GetContext(p->GetSuccessor()); break; } *pps++ = p; @@ -197,10 +220,10 @@ NO_LOOP: if (pps == ps) return pc; UpState.Symbol = *(Byte*) UpBranch; - UpState.Successor = (PPM_CONTEXT*) (((Byte*) UpBranch)+1); + UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1); if (pc->NumStats != 1) { - if ((p = pc->Stats)->Symbol != UpState.Symbol) + if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol) do { p++; } while (p->Symbol != UpState.Symbol); unsigned int cf = p->Freq-1; unsigned int s0 = pc->SummFreq - pc->NumStats - cf; @@ -224,11 +247,13 @@ NO_LOOP: PPM_CONTEXT::STATE fs = *FoundState, * p = NULL; PPM_CONTEXT* pc, * Successor; unsigned int ns1, ns, cf, sf, s0; - if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL) + if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0) { + pc = GetContextNoCheck(MinContext->Suffix); + if (pc->NumStats != 1) { - if ((p = pc->Stats)->Symbol != fs.Symbol) + if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol) { do { p++; } while (p->Symbol != fs.Symbol); if (p[0].Freq >= p[-1].Freq) @@ -251,8 +276,9 @@ NO_LOOP: } if ( !OrderFall ) { - MinContext = MaxContext = FoundState->Successor = CreateSuccessors(true, p); - if ( !MinContext ) + MinContext = MaxContext = CreateSuccessors(true, p); + FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext)); + if (MinContext == 0) goto RESTART_MODEL; return; } @@ -260,31 +286,36 @@ NO_LOOP: Successor = (PPM_CONTEXT*) SubAllocator.pText; if (SubAllocator.pText >= SubAllocator.UnitsStart) goto RESTART_MODEL; - if ( fs.Successor ) + if (fs.GetSuccessor() != 0) { - if ((Byte*) fs.Successor <= SubAllocator.pText && - (fs.Successor=CreateSuccessors(false, p)) == NULL) - goto RESTART_MODEL; + if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText) + { + PPM_CONTEXT* cs = CreateSuccessors(false, p); + fs.SetSuccessor(SubAllocator.GetOffset(cs)); + if (cs == NULL) + goto RESTART_MODEL; + } if ( !--OrderFall ) { - Successor = fs.Successor; + Successor = GetContext(fs.GetSuccessor()); SubAllocator.pText -= (MaxContext != MinContext); } } else { - FoundState->Successor = Successor; - fs.Successor = MinContext; + FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor)); + fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext)); } s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1); - for (pc = MaxContext; pc != MinContext; pc = pc->Suffix) + for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix)) { if ((ns1 = pc->NumStats) != 1) { if ((ns1 & 1) == 0) { - pc->Stats = (PPM_CONTEXT::STATE*) SubAllocator.ExpandUnits(pc->Stats, ns1 >> 1); - if ( !pc->Stats ) + void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1); + pc->Stats = SubAllocator.GetOffset(ppp); + if (!ppp) goto RESTART_MODEL; } pc->SummFreq += (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & @@ -296,7 +327,7 @@ NO_LOOP: if ( !p ) goto RESTART_MODEL; *p = pc->oneState(); - pc->Stats = p; + pc->Stats = SubAllocator.GetOffsetNoCheck(p); if (p->Freq < MAX_FREQ / 4 - 1) p->Freq += p->Freq; else @@ -315,13 +346,13 @@ NO_LOOP: cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); pc->SummFreq += cf; } - p = pc->Stats + ns1; - p->Successor = Successor; + p = GetState(pc->Stats) + ns1; + p->SetSuccessor(SubAllocator.GetOffset(Successor)); p->Symbol = fs.Symbol; p->Freq = cf; pc->NumStats = ++ns1; } - MaxContext = MinContext = fs.Successor; + MaxContext = MinContext = GetContext(fs.GetSuccessor()); return; RESTART_MODEL: RestartModelRare(); @@ -366,8 +397,11 @@ RESTART_MODEL: SEE2_CONTEXT* psee2c; if (MinContext->NumStats != 256) { - psee2c = SEE2Cont[NS2Indx[Diff-1]] + (Diff < MinContext->Suffix->NumStats - MinContext->NumStats)+ - 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 4 * (NumMasked > Diff) + HiBitsFlag; + psee2c = SEE2Cont[NS2Indx[Diff-1]] + + (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) + + 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + + 4 * (NumMasked > Diff) + + HiBitsFlag; scale = psee2c->getMean(); } else @@ -384,9 +418,10 @@ RESTART_MODEL: { int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq; PPM_CONTEXT::STATE* p1, * p; - for (p = FoundState; p != MinContext->Stats; p--) + PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats); + for (p = FoundState; p != stats; p--) _PPMD_SWAP(p[0], p[-1]); - MinContext->Stats->Freq += 4; + stats->Freq += 4; MinContext->SummFreq += 4; EscFreq = MinContext->SummFreq - p->Freq; Adder = (OrderFall != 0); @@ -398,7 +433,11 @@ RESTART_MODEL: if (p[0].Freq > p[-1].Freq) { PPM_CONTEXT::STATE tmp = *(p1 = p); - do { p1[0] = p1[-1]; } while (--p1 != MinContext->Stats && tmp.Freq > p1[-1].Freq); + do + { + p1[0] = p1[-1]; + } + while (--p1 != stats && tmp.Freq > p1[-1].Freq); *p1 = tmp; } } @@ -409,24 +448,24 @@ RESTART_MODEL: EscFreq += i; if ((MinContext->NumStats -= i) == 1) { - PPM_CONTEXT::STATE tmp = *MinContext->Stats; + PPM_CONTEXT::STATE tmp = *stats; do { tmp.Freq -= (tmp.Freq >> 1); EscFreq >>= 1; } while (EscFreq > 1); - SubAllocator.FreeUnits(MinContext->Stats, (OldNS+1) >> 1); + SubAllocator.FreeUnits(stats, (OldNS+1) >> 1); *(FoundState = &MinContext->oneState()) = tmp; return; } } MinContext->SummFreq += (EscFreq -= (EscFreq >> 1)); int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1; if (n0 != n1) - MinContext->Stats = - (PPM_CONTEXT::STATE*) SubAllocator.ShrinkUnits(MinContext->Stats, n0, n1); - FoundState = MinContext->Stats; + MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1)); + FoundState = GetState(MinContext->Stats); } void NextContext() { - if (!OrderFall && (Byte*) FoundState->Successor > SubAllocator.pText) - MinContext = MaxContext = FoundState->Successor; + PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor()); + if (!OrderFall && (Byte *)c > SubAllocator.pText) + MinContext = MaxContext = c; else { UpdateModel(); diff --git a/7zip/Compress/PPMD/PPMDDecode.h b/7zip/Compress/PPMD/PPMDDecode.h index 83445718..56afbe66 100755 --- a/7zip/Compress/PPMD/PPMDDecode.h +++ b/7zip/Compress/PPMD/PPMDDecode.h @@ -14,7 +14,7 @@ struct CDecodeInfo: public CInfo void DecodeBinSymbol(NRangeCoder::CDecoder *rangeDecoder) { PPM_CONTEXT::STATE& rs = MinContext->oneState(); - UInt16& bs = GetBinSumm(rs, MinContext->Suffix->NumStats); + UInt16& bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); if (rangeDecoder->DecodeBit(bs, TOT_BITS) == 0) { FoundState = &rs; @@ -36,13 +36,13 @@ struct CDecodeInfo: public CInfo void DecodeSymbol1(NRangeCoder::CDecoder *rangeDecoder) { - PPM_CONTEXT::STATE* p = MinContext->Stats; + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); int i, count, hiCnt; if ((count = rangeDecoder->GetThreshold(MinContext->SummFreq)) < (hiCnt = p->Freq)) { PrevSuccess = (2 * hiCnt > MinContext->SummFreq); RunLength += PrevSuccess; - rangeDecoder->Decode(0, MinContext->Stats->Freq); // MinContext->SummFreq); + rangeDecoder->Decode(0, p->Freq); // MinContext->SummFreq); (FoundState = p)->Freq=(hiCnt += 4); MinContext->SummFreq += 4; if (hiCnt > MAX_FREQ) @@ -72,7 +72,7 @@ struct CDecodeInfo: public CInfo int count, hiCnt, i = MinContext->NumStats - NumMasked; UInt32 freqSum; SEE2_CONTEXT* psee2c = makeEscFreq2(i, freqSum); - PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = MinContext->Stats-1; + PPM_CONTEXT::STATE* ps[256], ** pps = ps, * p = GetStateNoCheck(MinContext->Stats)-1; hiCnt = 0; do { @@ -119,8 +119,8 @@ struct CDecodeInfo: public CInfo do { OrderFall++; - MinContext = MinContext->Suffix; - if ( !MinContext ) + MinContext = GetContext(MinContext->Suffix); + if (MinContext == 0) return -1; } while (MinContext->NumStats == NumMasked); diff --git a/7zip/Compress/PPMD/PPMDDecoder.cpp b/7zip/Compress/PPMD/PPMDDecoder.cpp index 5677daf2..50200053 100755 --- a/7zip/Compress/PPMD/PPMDDecoder.cpp +++ b/7zip/Compress/PPMD/PPMDDecoder.cpp @@ -10,6 +10,9 @@ namespace NCompress { namespace NPPMD { +const int kLenIdFinished = -1; +const int kLenIdNeedInit = -2; + STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size) { if (size < 5) @@ -18,6 +21,15 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size _usedMemorySize = 0; for (int i = 0; i < 4; i++) _usedMemorySize += ((UInt32)(properties[1 + i])) << (i * 8); + + if (_usedMemorySize > kMaxMemBlockSize) + return E_NOTIMPL; + + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + return E_OUTOFMEMORY; + return S_OK; } @@ -25,76 +37,146 @@ class CDecoderFlusher { CDecoder *_coder; public: - CDecoderFlusher(CDecoder *coder): _coder(coder) {} + bool NeedFlush; + CDecoderFlusher(CDecoder *coder): _coder(coder), NeedFlush(true) {} ~CDecoderFlusher() { - _coder->Flush(); + if (NeedFlush) + _coder->Flush(); _coder->ReleaseStreams(); } }; -UInt32 GetMatchLen(const Byte *pointer1, const Byte *pointer2, - UInt32 limit) -{ - UInt32 i; - for(i = 0; i < limit && *pointer1 == *pointer2; - pointer1++, pointer2++, i++); - return i; +HRESULT CDecoder::CodeSpec(UInt32 size, Byte *memStream) +{ + const startSize = size; + if (_outSizeDefined) + { + const UInt64 rem = _outSize - _processedSize; + if (size > rem) + size = (UInt32)rem; + } + + if (_remainLen == kLenIdFinished) + return S_OK; + if (_remainLen == kLenIdNeedInit) + { + _rangeDecoder.Init(); + _remainLen = 0; + _info.MaxOrder = 0; + _info.StartModelRare(_order); + } + while (size != 0) + { + int symbol = _info.DecodeSymbol(&_rangeDecoder); + if (symbol < 0) + { + _remainLen = kLenIdFinished; + break; + } + if (memStream != 0) + *memStream++ = symbol; + else + _outStream.WriteByte((Byte)symbol); + size--; + } + _processedSize += startSize - size; + return S_OK; } STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - if (!_rangeDecoder.Create(1 << 20)) - return E_OUTOFMEMORY; if (!_outStream.Create(1 << 20)) return E_OUTOFMEMORY; - - _rangeDecoder.SetStream(inStream); - _rangeDecoder.Init(); + + SetInStream(inStream); _outStream.SetStream(outStream); - _outStream.Init(); - + SetOutStreamSize(outSize); CDecoderFlusher flusher(this); - UInt64 progressPosValuePrev = 0, pos = 0; - - if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) - return E_OUTOFMEMORY; - - // _info.Init(); - // _info.MaxOrder = _order; - _info.MaxOrder = 0; - _info.StartModelRare(_order); - - UInt64 size = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize; - - while(pos < size) + while(true) { - pos++; - int symbol = _info.DecodeSymbol(&_rangeDecoder); - if (symbol < 0) - return S_OK; - _outStream.WriteByte(symbol); - if (pos - progressPosValuePrev >= (1 << 18) && progress != NULL) + _processedSize = _outStream.GetProcessedSize(); + UInt32 curSize = (1 << 18); + RINOK(CodeSpec(curSize, NULL)); + if (_remainLen == kLenIdFinished) + break; + if (progress != NULL) { UInt64 inSize = _rangeDecoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&inSize, &pos)); - progressPosValuePrev = pos; + RINOK(progress->SetRatioInfo(&inSize, &_processedSize)); } + if (_outSizeDefined) + if (_outStream.GetProcessedSize() >= _outSize) + break; } - return S_OK; + flusher.NeedFlush = false; + return Flush(); } +#ifdef _NO_EXCEPTIONS + +#define PPMD_TRY_BEGIN +#define PPMD_TRY_END + +#else + +#define PPMD_TRY_BEGIN try { +#define PPMD_TRY_END } \ + catch(const CInBufferException &e) { return e.ErrorCode; } \ + catch(const COutBufferException &e) { return e.ErrorCode; } \ + catch(...) { return S_FALSE; } + +#endif + + STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) { - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const COutBufferException &e) { return e.ErrorCode; } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(...) { return E_FAIL; } + PPMD_TRY_BEGIN + return CodeReal(inStream, outStream, inSize, outSize, progress); + PPMD_TRY_END +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; } +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + if (_outSizeDefined = (outSize != NULL)) + _outSize = *outSize; + _remainLen = kLenIdNeedInit; + _outStream.Init(); + return S_OK; +} + +#ifdef _ST_MODE + +STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + PPMD_TRY_BEGIN + if (processedSize) + *processedSize = 0; + const UInt64 startPos = _processedSize; + RINOK(CodeSpec(size, (Byte *)data)); + if (processedSize) + *processedSize = (UInt32)(_processedSize - startPos); + return Flush(); + PPMD_TRY_END +} + +#endif + }} diff --git a/7zip/Compress/PPMD/PPMDDecoder.h b/7zip/Compress/PPMD/PPMDDecoder.h index a5c2d18e..bbb68ac5 100755 --- a/7zip/Compress/PPMD/PPMDDecoder.h +++ b/7zip/Compress/PPMD/PPMDDecoder.h @@ -17,6 +17,11 @@ namespace NPPMD { class CDecoder : public ICompressCoder, public ICompressSetDecoderProperties2, + #ifdef _ST_MODE + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public ISequentialInStream, + #endif public CMyUnknownImp { NRangeCoder::CDecoder _rangeDecoder; @@ -28,13 +33,28 @@ class CDecoder : Byte _order; UInt32 _usedMemorySize; + int _remainLen; + UInt64 _outSize; + bool _outSizeDefined; + UInt64 _processedSize; + + HRESULT CodeSpec(UInt32 num, Byte *memStream); public: - MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + #ifdef _ST_MODE + MY_UNKNOWN_IMP4( + ICompressSetDecoderProperties2, + ICompressSetInStream, + ICompressSetOutStreamSize, + ISequentialInStream) + #else + MY_UNKNOWN_IMP1( + ICompressSetDecoderProperties2) + #endif void ReleaseStreams() { - _rangeDecoder.ReleaseStream(); + ReleaseInStream(); _outStream.ReleaseStream(); } @@ -51,6 +71,17 @@ public: STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + #ifdef _ST_MODE + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + #endif + + CDecoder(): _outSizeDefined(false) {} + }; }} diff --git a/7zip/Compress/PPMD/PPMDEncode.h b/7zip/Compress/PPMD/PPMDEncode.h index c2342058..860310a2 100755 --- a/7zip/Compress/PPMD/PPMDEncode.h +++ b/7zip/Compress/PPMD/PPMDEncode.h @@ -15,7 +15,7 @@ struct CEncodeInfo: public CInfo void EncodeBinSymbol(int symbol, NRangeCoder::CEncoder *rangeEncoder) { PPM_CONTEXT::STATE& rs = MinContext->oneState(); - UInt16 &bs = GetBinSumm(rs, MinContext->Suffix->NumStats); + UInt16 &bs = GetBinSumm(rs, GetContextNoCheck(MinContext->Suffix)->NumStats); if (rs.Symbol == symbol) { FoundState = &rs; @@ -39,12 +39,12 @@ struct CEncodeInfo: public CInfo void EncodeSymbol1(int symbol, NRangeCoder::CEncoder *rangeEncoder) { - PPM_CONTEXT::STATE* p = MinContext->Stats; + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats); if (p->Symbol == symbol) { PrevSuccess = (2 * (p->Freq) > MinContext->SummFreq); RunLength += PrevSuccess; - rangeEncoder->Encode(0, MinContext->Stats->Freq, MinContext->SummFreq); + rangeEncoder->Encode(0, p->Freq, MinContext->SummFreq); (FoundState = p)->Freq += 4; MinContext->SummFreq += 4; if (p->Freq > MAX_FREQ) @@ -76,7 +76,7 @@ struct CEncodeInfo: public CInfo int hiCnt, i = MinContext->NumStats - NumMasked; UInt32 scale; SEE2_CONTEXT* psee2c = makeEscFreq2(i, scale); - PPM_CONTEXT::STATE* p = MinContext->Stats - 1; + PPM_CONTEXT::STATE* p = GetStateNoCheck(MinContext->Stats) - 1; hiCnt = 0; do { @@ -126,8 +126,8 @@ SYMBOL_FOUND: do { OrderFall++; - MinContext = MinContext->Suffix; - if ( !MinContext ) + MinContext = GetContext(MinContext->Suffix); + if (MinContext == 0) return; // S_OK; } while (MinContext->NumStats == NumMasked); diff --git a/7zip/Compress/PPMD/PPMDEncoder.cpp b/7zip/Compress/PPMD/PPMDEncoder.cpp index 16eaea60..b661f018 100755 --- a/7zip/Compress/PPMD/PPMDEncoder.cpp +++ b/7zip/Compress/PPMD/PPMDEncoder.cpp @@ -9,6 +9,8 @@ #include "Common/Defs.h" +#include "../../Common/StreamUtils.h" + #include "PPMDEncoder.h" namespace NCompress { @@ -40,19 +42,7 @@ public: } }; - CCounter g_Counter; - - -/* -// ISetRangeEncoder -STDMETHODIMP CEncoder::SetRangeEncoder(CRangeEncoder *aRangeEncoder) -{ - _rangeEncoder = aRangeEncoder; - RINOK(_rangeEncoder.QueryInterface(&m_InitOutCoder)); - - return S_OK; -} */ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, @@ -60,22 +50,22 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, { for (UInt32 i = 0; i < numProperties; i++) { - const PROPVARIANT &aProperty = properties[i]; + const PROPVARIANT &prop = properties[i]; switch(propIDs[i]) { case NCoderPropID::kUsedMemorySize: - if (aProperty.vt != VT_UI4) + if (prop.vt != VT_UI4) return E_INVALIDARG; - if (aProperty.ulVal < kMinMemSize) + if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize) return E_INVALIDARG; - _usedMemorySize = aProperty.ulVal; + _usedMemorySize = (UInt32)prop.ulVal; break; case NCoderPropID::kOrder: - if (aProperty.vt != VT_UI4) + if (prop.vt != VT_UI4) return E_INVALIDARG; - if (aProperty.ulVal < kMinOrder || aProperty.ulVal > kMaxOrderCompress) + if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress) return E_INVALIDARG; - _order = Byte(aProperty.ulVal); + _order = (Byte)prop.ulVal; break; default: return E_INVALIDARG; @@ -91,7 +81,7 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) properties[0] = _order; for (int i = 0; i < 4; i++) properties[1 + i] = Byte(_usedMemorySize >> (8 * i)); - return outStream->Write(properties, kPropSize, NULL); + return WriteStream(outStream, properties, kPropSize, NULL); } const UInt32 kUsedMemorySizeDefault = (1 << 24); @@ -101,30 +91,9 @@ CEncoder::CEncoder(): _usedMemorySize(kUsedMemorySizeDefault), _order(kOrderDefault) { - // SubAllocator.StartSubAllocator(kSubAllocator); } -HRESULT CEncoder::Flush() -{ - _rangeEncoder.FlushData(); - return _rangeEncoder.FlushStream(); -} - -class CEncoderFlusher -{ - CEncoder *_encoder; -public: - CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {} - ~CEncoderFlusher() - { - _encoder->Flush(); - _encoder->ReleaseStreams(); - } -}; - - - HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, @@ -134,50 +103,41 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, return E_OUTOFMEMORY; if (!_rangeEncoder.Create(1 << 20)) return E_OUTOFMEMORY; + if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) + return E_OUTOFMEMORY; _inStream.SetStream(inStream); _inStream.Init(); + _rangeEncoder.SetStream(outStream); _rangeEncoder.Init(); CEncoderFlusher flusher(this); - UInt64 pos = 0; - UInt64 prevProgressPos = 0; - - try - { - if ( !_info.SubAllocator.StartSubAllocator(_usedMemorySize) ) - return E_OUTOFMEMORY; - } - catch(...) - { - return E_OUTOFMEMORY; - } - - _info.MaxOrder = 0; _info.StartModelRare(_order); - - while (true) + while(true) { - Byte symbol; - if (!_inStream.ReadByte(symbol)) + UInt32 size = (1 << 18); + do { - // here we can write End Mark for stream version. - // In current version this feature is not used. - // _info.EncodeSymbol(-1, &_rangeEncoder); - - return S_OK; + Byte symbol; + if (!_inStream.ReadByte(symbol)) + { + // here we can write End Mark for stream version. + // In current version this feature is not used. + // _info.EncodeSymbol(-1, &_rangeEncoder); + return S_OK; + } + _info.EncodeSymbol(symbol, &_rangeEncoder); } - _info.EncodeSymbol(symbol, &_rangeEncoder); - pos++; - if (pos - prevProgressPos >= (1 << 18) && progress != NULL) + while (--size != 0); + if (progress != NULL) { + UInt64 inSize = _inStream.GetProcessedSize(); UInt64 outSize = _rangeEncoder.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&pos, &outSize)); - prevProgressPos = pos; + RINOK(progress->SetRatioInfo(&inSize, &outSize)); } } } @@ -193,4 +153,3 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, } }} - diff --git a/7zip/Compress/PPMD/PPMDEncoder.h b/7zip/Compress/PPMD/PPMDEncoder.h index 80ac7391..915180b9 100755 --- a/7zip/Compress/PPMD/PPMDEncoder.h +++ b/7zip/Compress/PPMD/PPMDEncoder.h @@ -29,14 +29,12 @@ public: UInt32 _usedMemorySize; Byte _order; -public: - - MY_UNKNOWN_IMP2( - ICompressSetCoderProperties, - ICompressWriteCoderProperties) + HRESULT Flush() + { + _rangeEncoder.FlushData(); + return _rangeEncoder.FlushStream(); + } - // ICoder interface - HRESULT Flush(); void ReleaseStreams() { _inStream.ReleaseStream(); @@ -46,6 +44,25 @@ public: HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); + + class CEncoderFlusher + { + CEncoder *_encoder; + public: + CEncoderFlusher(CEncoder *encoder): _encoder(encoder) {} + ~CEncoderFlusher() + { + _encoder->Flush(); + _encoder->ReleaseStreams(); + } + }; + +public: + + MY_UNKNOWN_IMP2( + ICompressSetCoderProperties, + ICompressWriteCoderProperties) + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); diff --git a/7zip/Compress/PPMD/PPMDSubAlloc.h b/7zip/Compress/PPMD/PPMDSubAlloc.h index 5a333fe3..fd64d577 100755 --- a/7zip/Compress/PPMD/PPMDSubAlloc.h +++ b/7zip/Compress/PPMD/PPMDSubAlloc.h @@ -11,39 +11,47 @@ const UINT N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; const UINT UNIT_SIZE=12, N_INDEXES=N1+N2+N3+N4; -#pragma pack(1) +// Extra 1 * UNIT_SIZE for NULL support +// Extra 2 * UNIT_SIZE for s0 in GlueFreeBlocks() +const UInt32 kExtraSize = (UNIT_SIZE * 3); +const UInt32 kMaxMemBlockSize = 0xFFFFFFFF - kExtraSize; + struct MEM_BLK { UInt16 Stamp, NU; - MEM_BLK *Next, *Prev; - void InsertAt(MEM_BLK* p) + UInt32 Next, Prev; + void InsertAt(Byte *Base, UInt32 p) { - Next = (Prev = p)->Next; - p->Next = Next->Prev = this; + Prev = p; + MEM_BLK *pp = (MEM_BLK *)(Base + p); + Next = pp->Next; + pp->Next = ((MEM_BLK *)(Base + Next))->Prev = (Byte *)this - Base; } - void Remove() + void Remove(Byte *Base) { - Prev->Next=Next; - Next->Prev=Prev; + ((MEM_BLK *)(Base + Prev))->Next = Next; + ((MEM_BLK *)(Base + Next))->Prev = Prev; } -} _PACK_ATTR; -#pragma pack() +}; class CSubAllocator { UInt32 SubAllocatorSize; Byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; - struct NODE { NODE* Next; } FreeList[N_INDEXES]; + UInt32 FreeList[N_INDEXES]; + + Byte *Base; + Byte *HeapStart, *LoUnit, *HiUnit; public: - Byte* HeapStart, *pText, *UnitsStart, *LoUnit, *HiUnit; + Byte *pText, *UnitsStart; CSubAllocator(): SubAllocatorSize(0), GlueCount(0), - pText(0), - UnitsStart(0), LoUnit(0), - HiUnit(0) + HiUnit(0), + pText(0), + UnitsStart(0) { memset(Indx2Units, 0, sizeof(Indx2Units)); memset(FreeList, 0, sizeof(FreeList)); @@ -53,21 +61,28 @@ public: StopSubAllocator(); }; + void *GetPtr(UInt32 offset) const { return (offset == 0) ? 0 : (void *)(Base + offset); } + void *GetPtrNoCheck(UInt32 offset) const { return (void *)(Base + offset); } + UInt32 GetOffset(void *ptr) const { return (ptr == 0) ? 0 : (UInt32)((Byte *)ptr - Base); } + UInt32 GetOffsetNoCheck(void *ptr) const { return (UInt32)((Byte *)ptr - Base); } + MEM_BLK *GetBlk(UInt32 offset) const { return (MEM_BLK *)(Base + offset); } + UInt32 *GetNode(UInt32 offset) const { return (UInt32 *)(Base + offset); } void InsertNode(void* p, int indx) { - ((NODE*) p)->Next = FreeList[indx].Next; - FreeList[indx].Next = (NODE*)p; + *(UInt32 *)p = FreeList[indx]; + FreeList[indx] = GetOffsetNoCheck(p); } void* RemoveNode(int indx) { - NODE* RetVal = FreeList[indx].Next; - FreeList[indx].Next = RetVal->Next; - return RetVal; + UInt32 offset = FreeList[indx]; + UInt32 *p = GetNode(offset); + FreeList[indx] = *p; + return (void *)p; } - UINT U2B(int NU) { return 8 * NU + 4 * NU; } + UINT U2B(int NU) const { return (UINT)(NU) * UNIT_SIZE; } void SplitBlock(void* pv, int oldIndx, int newIndx) { @@ -82,25 +97,22 @@ public: InsertNode(p, Units2Indx[UDiff - 1]); } - UInt32 GetUsedMemory() + UInt32 GetUsedMemory() const { - UInt32 i, k, RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText); - for (k = i = 0; i < N_INDEXES; i++, k = 0) - { - for (NODE* pn = FreeList + i;(pn = pn->Next) != NULL; k++) - ; - RetVal -= UNIT_SIZE*Indx2Units[i] * k; - } + UInt32 RetVal = SubAllocatorSize - (UInt32)(HiUnit - LoUnit) - (UInt32)(UnitsStart - pText); + for (UInt32 i = 0; i < N_INDEXES; i++) + for (UInt32 pn = FreeList[i]; pn != 0; RetVal -= (UInt32)Indx2Units[i] * UNIT_SIZE) + pn = *GetNode(pn); return (RetVal >> 2); } void StopSubAllocator() { - if ( SubAllocatorSize ) + if (SubAllocatorSize != 0) { - BigFree(HeapStart); + BigFree(Base); SubAllocatorSize = 0; - HeapStart = 0; + Base = 0; } } @@ -110,10 +122,13 @@ public: return true; StopSubAllocator(); if (size == 0) - HeapStart = 0; + Base = 0; else - if ((HeapStart = (Byte *)::BigAlloc(size)) == 0) + { + if ((Base = (Byte *)::BigAlloc(size + kExtraSize)) == 0) return false; + HeapStart = Base + UNIT_SIZE; // we need such code to support NULL; + } SubAllocatorSize = size; return true; } @@ -138,34 +153,52 @@ public: void GlueFreeBlocks() { - MEM_BLK s0, *p, *p1; - int i, k, sz; + UInt32 s0 = (UInt32)(HeapStart + SubAllocatorSize - Base); + + // We need add exta MEM_BLK with Stamp=0 + GetBlk(s0)->Stamp = 0; + s0 += UNIT_SIZE; + MEM_BLK *ps0 = GetBlk(s0); + + UInt32 p; + int i; if (LoUnit != HiUnit) *LoUnit=0; - for (i = 0, s0.Next = s0.Prev = &s0; i < N_INDEXES; i++) - while ( FreeList[i].Next ) + ps0->Next = ps0->Prev = s0; + + for (i = 0; i < N_INDEXES; i++) + while (FreeList[i] != 0) { - p = (MEM_BLK*) RemoveNode(i); - p->InsertAt(&s0); - p->Stamp = 0xFFFF; - p->NU = Indx2Units[i]; + MEM_BLK *pp = (MEM_BLK *)RemoveNode(i); + pp->InsertAt(Base, s0); + pp->Stamp = 0xFFFF; + pp->NU = Indx2Units[i]; } - for (p=s0.Next; p != &s0; p =p->Next) - while ((p1 = p + p->NU)->Stamp == 0xFFFF && int(p->NU) + p1->NU < 0x10000) + for (p = ps0->Next; p != s0; p = GetBlk(p)->Next) + { + while (true) { - p1->Remove(); - p->NU += p1->NU; + MEM_BLK *pp = GetBlk(p); + MEM_BLK *pp1 = GetBlk(p + pp->NU * UNIT_SIZE); + if (pp1->Stamp != 0xFFFF || int(pp->NU) + pp1->NU >= 0x10000) + break; + pp1->Remove(Base); + pp->NU += pp1->NU; } - while ((p=s0.Next) != &s0) + } + while ((p = ps0->Next) != s0) { - for (p->Remove(), sz=p->NU; sz > 128; sz -= 128, p += 128) - InsertNode(p, N_INDEXES - 1); + MEM_BLK *pp = GetBlk(p); + pp->Remove(Base); + int sz; + for (sz = pp->NU; sz > 128; sz -= 128, p += 128 * UNIT_SIZE) + InsertNode(Base + p, N_INDEXES - 1); if (Indx2Units[i = Units2Indx[sz-1]] != sz) { - k = sz-Indx2Units[--i]; - InsertNode(p + (sz - k), k - 1); + int k = sz - Indx2Units[--i]; + InsertNode(Base + p + (sz - k) * UNIT_SIZE, k - 1); } - InsertNode(p,i); + InsertNode(Base + p, i); } } void* AllocUnitsRare(int indx) @@ -174,7 +207,7 @@ public: { GlueCount = 255; GlueFreeBlocks(); - if (FreeList[indx].Next) + if (FreeList[indx] != 0) return RemoveNode(indx); } int i = indx; @@ -186,7 +219,7 @@ public: i = U2B(Indx2Units[indx]); return (UnitsStart - pText > i) ? (UnitsStart -= i) : (NULL); } - } while (!FreeList[i].Next); + } while (FreeList[i] == 0); void* RetVal = RemoveNode(i); SplitBlock(RetVal, i, indx); return RetVal; @@ -195,7 +228,7 @@ public: void* AllocUnits(int NU) { int indx = Units2Indx[NU - 1]; - if (FreeList[indx].Next) + if (FreeList[indx] != 0) return RemoveNode(indx); void* RetVal = LoUnit; LoUnit += U2B(Indx2Units[indx]); @@ -209,7 +242,7 @@ public: { if (HiUnit != LoUnit) return (HiUnit -= UNIT_SIZE); - if (FreeList->Next) + if (FreeList[0] != 0) return RemoveNode(0); return AllocUnitsRare(0); } @@ -233,7 +266,7 @@ public: int i0 = Units2Indx[oldNU - 1], i1 = Units2Indx[newNU - 1]; if (i0 == i1) return oldPtr; - if ( FreeList[i1].Next ) + if (FreeList[i1] != 0) { void* ptr = RemoveNode(i1); memcpy(ptr, oldPtr, U2B(newNU)); diff --git a/7zip/Compress/PPMD/PPMDType.h b/7zip/Compress/PPMD/PPMDType.h index 5a67ac84..5200fa54 100755 --- a/7zip/Compress/PPMD/PPMDType.h +++ b/7zip/Compress/PPMD/PPMDType.h @@ -13,12 +13,6 @@ const int kMaxOrderCompress = 32; const int MAX_O = 255; /* maximum allowed model order */ -#if defined(__GNUC__) -#define _PACK_ATTR __attribute__ ((packed)) -#else -#define _PACK_ATTR -#endif /* defined(__GNUC__) */ - template <class T> inline void _PPMD_SWAP(T& t1,T& t2) { T tmp = t1; t1 = t2; t2 = tmp; } diff --git a/7zip/Compress/PPMD/makefile b/7zip/Compress/PPMD/makefile index 9f12f423..2e687a70 100755 --- a/7zip/Compress/PPMD/makefile +++ b/7zip/Compress/PPMD/makefile @@ -16,6 +16,7 @@ COMMON_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\InBuffer.obj \ $O\OutBuffer.obj \ + $O\StreamUtils.obj \ OBJS = \ diff --git a/7zip/Compress/Quantum/QuantumDecoder.cpp b/7zip/Compress/Quantum/QuantumDecoder.cpp new file mode 100755 index 00000000..8dcd736a --- /dev/null +++ b/7zip/Compress/Quantum/QuantumDecoder.cpp @@ -0,0 +1,174 @@ +// QuantumDecoder.cpp + +#include "StdAfx.h" + +#include "QuantumDecoder.h" +#include "../../../Common/Defs.h" + +namespace NCompress { +namespace NQuantum { + +const UInt32 kDictionarySizeMax = (1 << 21); + +const int kLenIdNeedInit = -2; + +void CDecoder::Init() +{ + m_Selector.Init(kNumSelectors); + for (unsigned int i = 0; i < kNumLitSelectors; i++) + m_Literals[i].Init(kNumLitSymbols); + unsigned int numItems = _numDictBits << 1; + m_PosSlot[0].Init(MyMin(numItems, kNumLen3PosSymbolsMax)); + m_PosSlot[1].Init(MyMin(numItems, kNumLen4PosSymbolsMax)); + m_PosSlot[2].Init(MyMin(numItems, kNumLen5PosSymbolsMax)); + m_LenSlot.Init(kNumLenSymbols); +} + +HRESULT CDecoder::CodeSpec(UInt32 curSize) +{ + if (_remainLen == kLenIdNeedInit) + { + if (!_keepHistory) + { + if (!_outWindowStream.Create(_dictionarySize)) + return E_OUTOFMEMORY; + Init(); + } + if (!_rangeDecoder.Create(1 << 20)) + return E_OUTOFMEMORY; + _rangeDecoder.Init(); + _remainLen = 0; + } + if (curSize == 0) + return S_OK; + + while(_remainLen > 0 && curSize > 0) + { + _remainLen--; + Byte b = _outWindowStream.GetByte(_rep0); + _outWindowStream.PutByte(b); + curSize--; + } + + while(curSize > 0) + { + if (_rangeDecoder.Stream.WasFinished()) + return S_FALSE; + + unsigned int selector = m_Selector.Decode(&_rangeDecoder); + if (selector < kNumLitSelectors) + { + Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&_rangeDecoder)); + _outWindowStream.PutByte(b); + curSize--; + } + else + { + selector -= kNumLitSelectors; + unsigned int len = selector + kMatchMinLen; + if (selector == 2) + { + unsigned int lenSlot = m_LenSlot.Decode(&_rangeDecoder);; + if (lenSlot >= kNumSimpleLenSlots) + { + lenSlot -= 2; + int numDirectBits = (int)(lenSlot >> 2); + len += ((4 | (lenSlot & 3)) << numDirectBits) - 2; + if (numDirectBits < 6) + len += _rangeDecoder.Stream.ReadBits(numDirectBits); + } + else + len += lenSlot; + } + UInt32 rep0 = m_PosSlot[selector].Decode(&_rangeDecoder);; + if (rep0 >= kNumSimplePosSlots) + { + int numDirectBits = (int)((rep0 >> 1) - 1); + rep0 = ((2 | (rep0 & 1)) << numDirectBits) + _rangeDecoder.Stream.ReadBits(numDirectBits); + } + unsigned int locLen = len; + if (len > curSize) + locLen = (unsigned int)curSize; + if (!_outWindowStream.CopyBlock(rep0, locLen)) + return S_FALSE; + curSize -= locLen; + len -= locLen; + if (len != 0) + { + _remainLen = (int)len; + _rep0 = rep0; + break; + } + } + } + return _rangeDecoder.Stream.WasFinished() ? S_FALSE : S_OK; +} + +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, + const UInt64 *, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (outSize == NULL) + return E_INVALIDARG; + UInt64 size = *outSize; + const UInt64 startSize = size; + + SetInStream(inStream); + _outWindowStream.SetStream(outStream); + SetOutStreamSize(outSize); + CDecoderFlusher flusher(this); + + const UInt64 start = _outWindowStream.GetProcessedSize(); + while(true) + { + UInt32 curSize = 1 << 18; + UInt64 rem = size - (_outWindowStream.GetProcessedSize() - start); + if (curSize > rem) + curSize = (UInt32)rem; + if (curSize == 0) + break; + RINOK(CodeSpec(curSize)); + if (progress != NULL) + { + UInt64 inSize = _rangeDecoder.GetProcessedSize(); + UInt64 nowPos64 = _outWindowStream.GetProcessedSize() - start; + RINOK(progress->SetRatioInfo(&inSize, &nowPos64)); + } + } + flusher.NeedFlush = false; + return Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CInBufferException &e) { return e.ErrorCode; } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream) +{ + _rangeDecoder.SetStream(inStream); + return S_OK; +} + +STDMETHODIMP CDecoder::ReleaseInStream() +{ + _rangeDecoder.ReleaseStream(); + return S_OK; +} + +STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize) +{ + if (outSize == NULL) + return E_FAIL; + _remainLen = kLenIdNeedInit; + _outWindowStream.Init(_keepHistory); + return S_OK; +} + +}} diff --git a/7zip/Compress/Quantum/QuantumDecoder.h b/7zip/Compress/Quantum/QuantumDecoder.h new file mode 100755 index 00000000..2574368f --- /dev/null +++ b/7zip/Compress/Quantum/QuantumDecoder.h @@ -0,0 +1,287 @@ +// QuantumDecoder.h + +#ifndef __QUANTUM_DECODER_H +#define __QUANTUM_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../Common/InBuffer.h" +#include "../../ICoder.h" +#include "../LZ/LZOutWindow.h" + +namespace NCompress { +namespace NQuantum { + +class CStreamBitDecoder +{ + UInt32 m_Value; + CInBuffer m_Stream; +public: + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} + void ReleaseStream() { m_Stream.ReleaseStream();} + + void Finish() { m_Value = 0x10000; } + + void Init() + { + m_Stream.Init(); + m_Value = 0x10000; + } + + UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize(); } + bool WasFinished() const { return m_Stream.WasFinished(); }; + + UInt32 ReadBit() + { + if (m_Value >= 0x10000) + m_Value = 0x100 | m_Stream.ReadByte(); + UInt32 res = (m_Value >> 7) & 1; + m_Value <<= 1; + return res; + } + + UInt32 ReadBits(int numBits) // numBits > 0 + { + UInt32 res = 0; + do + res = (res << 1) | ReadBit(); + while(--numBits != 0); + return res; + } +}; + +const int kNumLitSelectorBits = 2; +const unsigned int kNumLitSelectors = (1 << kNumLitSelectorBits); +const unsigned int kNumLitSymbols = 1 << (8 - kNumLitSelectorBits); +const unsigned int kNumMatchSelectors = 3; +const unsigned int kNumSelectors = kNumLitSelectors + kNumMatchSelectors; +const unsigned int kNumLen3PosSymbolsMax = 24; +const unsigned int kNumLen4PosSymbolsMax = 36; +const unsigned int kNumLen5PosSymbolsMax = 42; +const unsigned int kNumLenSymbols = 27; + +const unsigned int kNumSymbolsMax = kNumLitSymbols; // 64 + +const unsigned int kMatchMinLen = 3; +const unsigned int kNumSimplePosSlots = 4; +const unsigned int kNumSimpleLenSlots = 6; + +namespace NRangeCoder { + +class CDecoder +{ + UInt32 Low; + UInt32 Range; + UInt32 Code; +public: + CStreamBitDecoder Stream; + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } + void ReleaseStream() { Stream.ReleaseStream(); } + + void Init() + { + Stream.Init(); + Low = 0; + Range = 0x10000; + Code = Stream.ReadBits(16); + } + + void Finish() + { + // we need these extra two Bit_reads + Stream.ReadBit(); + Stream.ReadBit(); + Stream.Finish(); + } + + UInt64 GetProcessedSize() const { return Stream.GetProcessedSize(); } + + UInt32 GetThreshold(UInt32 total) const + { + return ((Code + 1) * total - 1) / Range; // & 0xFFFF is not required; + } + + void Decode(UInt32 start, UInt32 end, UInt32 total) + { + UInt32 high = Low + end * Range / total - 1; + UInt32 offset = start * Range / total; + Code -= offset; + Low += offset; + while (true) + { + if ((Low & 0x8000) != (high & 0x8000)) + { + if ((Low & 0x4000) == 0 || (high & 0x4000) != 0) + break; + Low &= 0x3FFF; + high |= 0x4000; + } + Low = (Low << 1) & 0xFFFF; + high = ((high << 1) | 1) & 0xFFFF; + Code = ((Code << 1) | Stream.ReadBit()); + } + Range = high - Low + 1; + } +}; + +const UInt16 kUpdateStep = 8; +const UInt16 kFreqSumMax = 3800; +const UInt16 kReorderCountStart = 4; +const UInt16 kReorderCount = 50; + +class CModelDecoder +{ + unsigned int NumItems; + unsigned int ReorderCount; + UInt16 Freqs[kNumSymbolsMax + 1]; + Byte Values[kNumSymbolsMax]; +public: + void Init(unsigned int numItems) + { + NumItems = numItems; + ReorderCount = kReorderCountStart; + for(unsigned int i = 0; i < numItems; i++) + { + Freqs[i] = (UInt16)(numItems - i); + Values[i] = (Byte)i; + } + Freqs[numItems] = 0; + } + + unsigned int Decode(CDecoder *rangeDecoder) + { + UInt32 threshold = rangeDecoder->GetThreshold(Freqs[0]); + unsigned int i; + for (i = 1; Freqs[i] > threshold; i++); + rangeDecoder->Decode(Freqs[i], Freqs[i - 1], Freqs[0]); + unsigned int res = Values[--i]; + do + Freqs[i] += kUpdateStep; + while(i-- != 0); + + if (Freqs[0] > kFreqSumMax) + { + if (--ReorderCount == 0) + { + ReorderCount = kReorderCount; + for(i = 0; i < NumItems; i++) + Freqs[i] = ((Freqs[i] - Freqs[i + 1]) + 1) >> 1; + for(i = 0; i < NumItems - 1; i++) + for(unsigned int j = i + 1; j < NumItems; j++) + if (Freqs[i] < Freqs[j]) + { + UInt16 tmpFreq = Freqs[i]; + Byte tmpVal = Values[i]; + Freqs[i] = Freqs[j]; + Values[i] = Values[j]; + Freqs[j] = tmpFreq; + Values[j] = tmpVal; + } + do + Freqs[i] += Freqs[i + 1]; + while(i-- != 0); + } + else + { + i = NumItems - 1; + do + { + Freqs[i] >>= 1; + if (Freqs[i] <= Freqs[i + 1]) + Freqs[i] = Freqs[i + 1] + 1; + } + while(i-- != 0); + } + } + return res; + }; +}; + +} + +class CDecoder: + public ICompressCoder, + public ICompressSetInStream, + public ICompressSetOutStreamSize, + public CMyUnknownImp +{ + CLZOutWindow _outWindowStream; + NRangeCoder::CDecoder _rangeDecoder; + + /////////////////// + // State + UInt64 _outSize; + // UInt64 _nowPos64; + int _remainLen; // -1 means end of stream. // -2 means need Init + UInt32 _rep0; + + int _numDictBits; + UInt32 _dictionarySize; + + NRangeCoder::CModelDecoder m_Selector; + NRangeCoder::CModelDecoder m_Literals[kNumLitSelectors]; + NRangeCoder::CModelDecoder m_PosSlot[kNumMatchSelectors]; + NRangeCoder::CModelDecoder m_LenSlot; + + bool _keepHistory; + + void Init(); + HRESULT CodeSpec(UInt32 size); +public: + MY_UNKNOWN_IMP2( + ICompressSetInStream, + ICompressSetOutStreamSize) + + void ReleaseStreams() + { + _outWindowStream.ReleaseStream(); + ReleaseInStream(); + } + + class CDecoderFlusher + { + CDecoder *_decoder; + public: + bool NeedFlush; + CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} + ~CDecoderFlusher() + { + if (NeedFlush) + _decoder->Flush(); + _decoder->ReleaseStreams(); + } + }; + + HRESULT Flush() { return _outWindowStream.Flush(); } + + HRESULT CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetInStream)(ISequentialInStream *inStream); + STDMETHOD(ReleaseInStream)(); + STDMETHOD(SetOutStreamSize)(const UInt64 *outSize); + + void SetParams(int numDictBits) + { + _numDictBits = numDictBits; + _dictionarySize = (UInt32)1 << numDictBits; + } + void SetKeepHistory(bool keepHistory) + { + _keepHistory = keepHistory; + } + + CDecoder(): _keepHistory(false) {} + virtual ~CDecoder() {} +}; + +}} + +#endif diff --git a/7zip/Compress/Rar20/DllExports.cpp b/7zip/Compress/Rar20/DllExports.cpp new file mode 100755 index 00000000..599d71c3 --- /dev/null +++ b/7zip/Compress/Rar20/DllExports.cpp @@ -0,0 +1,66 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "Rar20Decoder.h" + +// {23170F69-40C1-278B-0403-020000000000} +DEFINE_GUID(CLSID_CCompressRar20Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + if (*clsid != CLSID_CCompressRar20Decoder) + return CLASS_E_CLASSNOTAVAILABLE; + if (*iid != IID_ICompressCoder) + return E_NOINTERFACE; + CMyComPtr<ICompressCoder> coder = (ICompressCoder *)new + NCompress::NRar20::CDecoder; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = 1; + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index != 0) + return E_INVALIDARG; + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NMethodPropID::kID: + { + const char id[] = { 0x04, 0x03, 0x02 }; + if ((value->bstrVal = ::SysAllocStringByteLen(id, sizeof(id))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(L"Rar20")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CCompressRar20Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/7zip/Compress/Rar20/Rar20Const.h b/7zip/Compress/Rar20/Rar20Const.h new file mode 100755 index 00000000..6c5fecb6 --- /dev/null +++ b/7zip/Compress/Rar20/Rar20Const.h @@ -0,0 +1,65 @@ +// Rar20CoderConst.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR20_CONST_H +#define __RAR20_CONST_H + +#include "Rar20ExtConst.h" + +namespace NCompress { +namespace NRar20 { + +const UInt32 kMainTableSize = 298; +const UInt32 kLenTableSize = 28; + +const UInt32 kDistTableStart = kMainTableSize; +const UInt32 kLenTableStart = kDistTableStart + kDistTableSize; + +const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize; + +const UInt32 kLevelTableSize = 19; + +const UInt32 kMMTablesSizesSum = kMMTableSize * 4; + +const UInt32 kMaxTableSize = kMMTablesSizesSum; + +const UInt32 kTableDirectLevels = 16; +const UInt32 kTableLevelRepNumber = kTableDirectLevels; +const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; +const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; + +const UInt32 kLevelMask = 0xF; + + +const UInt32 kRepBothNumber = 256; +const UInt32 kRepNumber = kRepBothNumber + 1; +const UInt32 kLen2Number = kRepNumber + 4; + +const UInt32 kLen2NumNumbers = 8; +const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers; +const UInt32 kMatchNumber = kReadTableNumber + 1; + +const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; +const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; + +const UInt32 kDistStart[kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; +const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; + +const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; + +const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192}; +const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6}; + +const UInt32 kDistLimit2 = 0x101 - 1; +const UInt32 kDistLimit3 = 0x2000 - 1; +const UInt32 kDistLimit4 = 0x40000 - 1; + +const UInt32 kMatchMaxLen = 255 + 2; +const UInt32 kMatchMaxLenMax = 255 + 5; +const UInt32 kNormalMatchMinLen = 3; + +}} + +#endif diff --git a/7zip/Compress/Rar20/Rar20Decoder.cpp b/7zip/Compress/Rar20/Rar20Decoder.cpp new file mode 100755 index 00000000..8da544f7 --- /dev/null +++ b/7zip/Compress/Rar20/Rar20Decoder.cpp @@ -0,0 +1,319 @@ +// Rar20Decoder.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#include "StdAfx.h" + +#include "Rar20Decoder.h" +#include "Rar20Const.h" + +namespace NCompress { +namespace NRar20 { + +class CException +{ +public: + enum ECauseType + { + kData + } Cause; + CException(ECauseType cause): Cause(cause) {} +}; + +static const char *kNumberErrorMessage = "Number error"; + +static const UInt32 kHistorySize = 1 << 20; + +static const int kNumStats = 11; + +static const UInt32 kWindowReservSize = (1 << 22) + 256; + +CDecoder::CDecoder(): + m_IsSolid(false) +{ +} + +void CDecoder::InitStructures() +{ + m_Predictor.Init(); + for(int i = 0; i < kNumRepDists; i++) + m_RepDists[i] = 0; + m_RepDistPtr = 0; + m_LastLength = 0; + memset(m_LastLevels, 0, kMaxTableSize); +} + +#define RIF(x) { if (!(x)) return false; } + +bool CDecoder::ReadTables(void) +{ + Byte levelLevels[kLevelTableSize]; + Byte newLevels[kMaxTableSize]; + m_AudioMode = (m_InBitStream.ReadBits(1) == 1); + + if (m_InBitStream.ReadBits(1) == 0) + memset(m_LastLevels, 0, kMaxTableSize); + int numLevels; + if (m_AudioMode) + { + m_NumChannels = m_InBitStream.ReadBits(2) + 1; + if (m_Predictor.CurrentChannel >= m_NumChannels) + m_Predictor.CurrentChannel = 0; + numLevels = m_NumChannels * kMMTableSize; + } + else + numLevels = kHeapTablesSizesSum; + + int i; + for (i = 0; i < kLevelTableSize; i++) + levelLevels[i] = Byte(m_InBitStream.ReadBits(4)); + RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); + i = 0; + while (i < numLevels) + { + UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); + if (number < kTableDirectLevels) + { + newLevels[i] = Byte((number + m_LastLevels[i]) & kLevelMask); + i++; + } + else + { + if (number == kTableLevelRepNumber) + { + int t = m_InBitStream.ReadBits(2) + 3; + for (int reps = t; reps > 0 && i < numLevels ; reps--, i++) + newLevels[i] = newLevels[i - 1]; + } + else + { + int num; + if (number == kTableLevel0Number) + num = m_InBitStream.ReadBits(3) + 3; + else if (number == kTableLevel0Number2) + num = m_InBitStream.ReadBits(7) + 11; + else + return false; + for (;num > 0 && i < numLevels; num--) + newLevels[i++] = 0; + } + } + } + if (m_AudioMode) + for (i = 0; i < m_NumChannels; i++) + { + RIF(m_MMDecoders[i].SetCodeLengths(&newLevels[i * kMMTableSize])); + } + else + { + RIF(m_MainDecoder.SetCodeLengths(&newLevels[0])); + RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); + RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); + } + memcpy(m_LastLevels, newLevels, kMaxTableSize); + return true; +} + +bool CDecoder::ReadLastTables() +{ + // it differs a little from pure RAR sources; + // UInt64 ttt = m_InBitStream.GetProcessedSize() + 2; + // + 2 works for: return 0xFF; in CInBuffer::ReadByte. + if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect; + // if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (m_AudioMode) + { + UInt32 symbol = m_MMDecoders[m_Predictor.CurrentChannel].DecodeSymbol(&m_InBitStream); + if (symbol == 256) + return ReadTables(); + if (symbol >= kMMTableSize) + return false; + } + else + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + if (number == kReadTableNumber) + return ReadTables(); + if (number >= kMainTableSize) + return false; + } + return true; +} + +class CCoderReleaser +{ + CDecoder *m_Coder; +public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + m_Coder->ReleaseStreams(); + } +}; + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + if (inSize == NULL || outSize == NULL) + return E_INVALIDARG; + + if (!m_OutWindowStream.Create(kHistorySize)) + return E_OUTOFMEMORY; + if (!m_InBitStream.Create(1 << 20)) + return E_OUTOFMEMORY; + + m_PackSize = *inSize; + + UInt64 pos = 0, unPackSize = *outSize; + + m_OutWindowStream.SetStream(outStream); + m_OutWindowStream.Init(m_IsSolid); + m_InBitStream.SetStream(inStream); + m_InBitStream.Init(); + + CCoderReleaser coderReleaser(this); + if (!m_IsSolid) + { + InitStructures(); + if (unPackSize == 0) + { + if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; + if (!ReadTables()) + return S_FALSE; + return S_OK; + } + if (!ReadTables()) + return S_FALSE; + } + + while(pos < unPackSize) + { + if (m_AudioMode) + while(pos < unPackSize) + { + UInt32 symbol = m_MMDecoders[m_Predictor.CurrentChannel].DecodeSymbol(&m_InBitStream); + if (symbol == 256) + { + if (progress != 0) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + if (!ReadTables()) + return S_FALSE; + break; + } + if (symbol >= kMMTableSize) + return S_FALSE; + Byte byPredict = m_Predictor.Predict(); + Byte byReal = byPredict - Byte(symbol); + m_Predictor.Update(byReal, byPredict); + m_OutWindowStream.PutByte(byReal); + if (++m_Predictor.CurrentChannel == m_NumChannels) + m_Predictor.CurrentChannel = 0; + pos++; + } + else + while(pos < unPackSize) + { + UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); + UInt32 length, distance; + if (number < 256) + { + m_OutWindowStream.PutByte(Byte(number)); + pos++; + continue; + } + else if (number >= kMatchNumber) + { + number -= kMatchNumber; + length = kNormalMatchMinLen + UInt32(kLenStart[number]) + + m_InBitStream.ReadBits(kLenDirectBits[number]); + number = m_DistDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kDistTableSize) + return S_FALSE; + distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); + if (distance >= kDistLimit3) + { + length += 2 - ((distance - kDistLimit4) >> 31); + // length++; + // if (distance >= kDistLimit4) + // length++; + } + } + else if (number == kRepBothNumber) + { + length = m_LastLength; + distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3]; + } + else if (number < kLen2Number) + { + distance = m_RepDists[(m_RepDistPtr - (number - kRepNumber + 1)) & 3]; + number = m_LenDecoder.DecodeSymbol(&m_InBitStream); + if (number >= kLenTableSize) + return S_FALSE; + length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); + if (distance >= kDistLimit2) + { + length++; + if (distance >= kDistLimit3) + { + length += 2 - ((distance - kDistLimit4) >> 31); + // length++; + // if (distance >= kDistLimit4) + // length++; + } + } + } + else if (number < kReadTableNumber) + { + number -= kLen2Number; + distance = kLen2DistStarts[number] + + m_InBitStream.ReadBits(kLen2DistDirectBits[number]); + length = 2; + } + else if (number == kReadTableNumber) + { + if (progress != 0) + { + UInt64 packSize = m_InBitStream.GetProcessedSize(); + RINOK(progress->SetRatioInfo(&packSize, &pos)); + } + if (!ReadTables()) + return S_FALSE; + break; + } + else + return S_FALSE; + CopyBackBlockOp(distance, length); + pos += length; + } + } + if (pos > unPackSize) + throw CException(CException::kData); + + if (!ReadLastTables()) + return S_FALSE; + return m_OutWindowStream.Flush(); +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CLZOutWindowException &e) { return e.ErrorCode; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +}} diff --git a/7zip/Compress/Rar20/Rar20Decoder.h b/7zip/Compress/Rar20/Rar20Decoder.h new file mode 100755 index 00000000..071b3635 --- /dev/null +++ b/7zip/Compress/Rar20/Rar20Decoder.h @@ -0,0 +1,95 @@ +// Rar20Decoder.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR20_DECODER_H +#define __RAR20_DECODER_H + +#include "../../../Common/MyCom.h" + +#include "../../ICoder.h" +#include "../../Common/MSBFDecoder.h" +#include "../../Common/InBuffer.h" + +#include "../LZ/LZOutWindow.h" +#include "../Huffman/HuffmanDecoder.h" + +#include "Rar20Multimedia.h" +#include "Rar20Const.h" + +namespace NCompress { +namespace NRar20 { + +typedef NStream::NMSBF::CDecoder<CInBuffer> CBitDecoder; + +const int kNumHuffmanBits = 15; + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + CLZOutWindow m_OutWindowStream; + CBitDecoder m_InBitStream; + NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; + NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder; + NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder; + NHuffman::CDecoder<kNumHuffmanBits, kMMTableSize> m_MMDecoders[NMultimedia::kNumChanelsMax]; + NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; + + bool m_AudioMode; + + NMultimedia::CPredictor m_Predictor; + int m_NumChannels; + + UInt32 m_RepDists[kNumRepDists]; + UInt32 m_RepDistPtr; + + UInt32 m_LastLength; + + Byte m_LastLevels[kMaxTableSize]; + + UInt64 m_PackSize; + bool m_IsSolid; + + void InitStructures(); + bool ReadTables(); + bool ReadLastTables(); + void CopyBackBlockOp(UInt32 aDistance, UInt32 aLength) + { + /* + if(m_Position <= aDistance) + throw CDecoderException(CDecoderException::kData); + */ + m_RepDists[m_RepDistPtr++ & 3] = aDistance; + m_LastLength = aLength; + m_OutWindowStream.CopyBlock(aDistance, aLength); + } + +public: + CDecoder(); + + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); + +}; + +}} + +#endif diff --git a/7zip/Compress/Rar20/Rar20ExtConst.h b/7zip/Compress/Rar20/Rar20ExtConst.h new file mode 100755 index 00000000..b74bc0cf --- /dev/null +++ b/7zip/Compress/Rar20/Rar20ExtConst.h @@ -0,0 +1,21 @@ +// Rar20ExtConst.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR20_EXTCONST_H +#define __RAR20_EXTCONST_H + +#include "../../../Common/Types.h" + +namespace NCompress { +namespace NRar20 { + +const UInt32 kNumRepDists = 4; +const UInt32 kDistTableSize = 48; + +const int kMMTableSize = 256 + 1; + +}} + +#endif diff --git a/7zip/Compress/Rar20/Rar20Multimedia.cpp b/7zip/Compress/Rar20/Rar20Multimedia.cpp new file mode 100755 index 00000000..3c0a13af --- /dev/null +++ b/7zip/Compress/Rar20/Rar20Multimedia.cpp @@ -0,0 +1,128 @@ +// Rar20Multimedia.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#include "StdAfx.h" + +#include "Rar20Multimedia.h" + +namespace NCompress { +namespace NRar20 { +namespace NMultimedia { + +void CAudioVariables::Init() +{ + memset(this, 0, sizeof(CAudioVariables)); +} + +void CPredictor::Init() +{ + for(int i = 0; i < kNumChanelsMax; i++) + m_AudioVariablesArray[i].Init(); + m_ChannelDelta = 0; + CurrentChannel = 0; +} + +Byte CPredictor::Predict() +{ + CAudioVariables *v = &m_AudioVariablesArray[CurrentChannel]; + v->ByteCount++; + v->D4 = v->D3; + v->D3 = v->D2; + v->D2 = v->LastDelta-v->D1; + v->D1 = v->LastDelta; + int pCh = 8 * v->LastChar + + v->K1 * v->D1 + + v->K2 * v->D2 + + v->K3 * v->D3 + + v->K4 * v->D4 + + v->K5*m_ChannelDelta; + pCh = (pCh >> 3) & 0xFF; + return Byte(pCh); +} + +void CPredictor::Update(Byte realValue, int predictedValue) +{ + struct CAudioVariables *v = &m_AudioVariablesArray[CurrentChannel]; + + int delta = predictedValue - realValue; + int i = ((signed char)delta) << 3; + + v->Dif[0] += abs(i); + v->Dif[1] += abs(i - v->D1); + v->Dif[2] += abs(i + v->D1); + v->Dif[3] += abs(i - v->D2); + v->Dif[4] += abs(i + v->D2); + v->Dif[5] += abs(i - v->D3); + v->Dif[6] += abs(i + v->D3); + v->Dif[7] += abs(i - v->D4); + v->Dif[8] += abs(i + v->D4); + v->Dif[9] += abs(i - m_ChannelDelta); + v->Dif[10] += abs(i + m_ChannelDelta); + + m_ChannelDelta = v->LastDelta = (signed char)(realValue - v->LastChar); + v->LastChar = realValue; + + UInt32 numMinDif, minDif; + if ((v->ByteCount & 0x1F)==0) + { + minDif = v->Dif[0]; + numMinDif = 0; + v->Dif[0] = 0; + for (i = 1; i < sizeof(v->Dif) / sizeof(v->Dif[0]); i++) + { + if (v->Dif[i] < minDif) + { + minDif = v->Dif[i]; + numMinDif = i; + } + v->Dif[i] = 0; + } + switch(numMinDif) + { + case 1: + if (v->K1 >= -16) + v->K1--; + break; + case 2: + if (v->K1 < 16) + v->K1++; + break; + case 3: + if (v->K2 >= -16) + v->K2--; + break; + case 4: + if (v->K2 < 16) + v->K2++; + break; + case 5: + if (v->K3 >= -16) + v->K3--; + break; + case 6: + if (v->K3 < 16) + v->K3++; + break; + case 7: + if (v->K4 >= -16) + v->K4--; + break; + case 8: + if (v->K4 < 16) + v->K4++; + break; + case 9: + if (v->K5 >= -16) + v->K5--; + break; + case 10: + if (v->K5 < 16) + v->K5++; + break; + } + } +} + +}}} diff --git a/7zip/Compress/Rar20/Rar20Multimedia.h b/7zip/Compress/Rar20/Rar20Multimedia.h new file mode 100755 index 00000000..7af86d07 --- /dev/null +++ b/7zip/Compress/Rar20/Rar20Multimedia.h @@ -0,0 +1,43 @@ +// Rar20Multimedia.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR20_MULTIMEDIA_H +#define __RAR20_MULTIMEDIA_H + +#include "../../../Common/Types.h" + +namespace NCompress { +namespace NRar20 { +namespace NMultimedia { + +struct CAudioVariables +{ + int K1,K2,K3,K4,K5; + int D1,D2,D3,D4; + int LastDelta; + UInt32 Dif[11]; + UInt32 ByteCount; + int LastChar; + + void Init(); +}; + +const int kNumChanelsMax = 4; + +class CPredictor +{ + CAudioVariables m_AudioVariablesArray[kNumChanelsMax]; + int m_ChannelDelta; +public: + int CurrentChannel; + + void Init(); + Byte Predict(); + void Update(Byte realValue, int predictedValue); +}; + +}}} + +#endif diff --git a/7zip/Compress/Rar20/StdAfx.cpp b/7zip/Compress/Rar20/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Compress/Rar20/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Compress/Rar20/StdAfx.h b/7zip/Compress/Rar20/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/Rar20/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/Rar29/DllExports.cpp b/7zip/Compress/Rar29/DllExports.cpp new file mode 100755 index 00000000..ed5197f8 --- /dev/null +++ b/7zip/Compress/Rar29/DllExports.cpp @@ -0,0 +1,105 @@ +// DLLExports.cpp + +#include "StdAfx.h" + +#include "Common/MyInitGuid.h" +#include "Common/ComTry.h" + +#include "../Rar20/Rar20Decoder.h" +#include "Rar29Decoder.h" + +// {23170F69-40C1-278B-0403-010000000000} +DEFINE_GUID(CLSID_CCompressRar15Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0403-020000000000} +DEFINE_GUID(CLSID_CCompressRar20Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00); + +// {23170F69-40C1-278B-0403-030000000000} +DEFINE_GUID(CLSID_CCompressRar29Decoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00); + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + return TRUE; +} + +STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject) +{ + COM_TRY_BEGIN + *outObject = 0; + + int correctInterface = (*iid == IID_ICompressCoder); + CMyComPtr<ICompressCoder> coder; + if (*clsid == CLSID_CCompressRar15Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NRar15::CDecoder; + } + else if (*clsid == CLSID_CCompressRar20Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NRar20::CDecoder; + } + else if (*clsid == CLSID_CCompressRar29Decoder) + { + if (!correctInterface) + return E_NOINTERFACE; + coder = (ICompressCoder *)new NCompress::NRar29::CDecoder; + } + else + return CLASS_E_CLASSNOTAVAILABLE; + *outObject = coder.Detach(); + COM_TRY_END + return S_OK; +} + +struct CRarMethodItem +{ + char ID[3]; + const wchar_t *UserName; + const GUID *Decoder; +}; + +static CRarMethodItem g_Methods[] = +{ + { { 0x04, 0x03, 0x01 }, L"Rar15", &CLSID_CCompressRar15Decoder }, + { { 0x04, 0x03, 0x02 }, L"Rar20", &CLSID_CCompressRar20Decoder }, + { { 0x04, 0x03, 0x03 }, L"Rar29", &CLSID_CCompressRar29Decoder } +}; + +STDAPI GetNumberOfMethods(UINT32 *numMethods) +{ + *numMethods = sizeof(g_Methods) / sizeof(g_Methods[1]); + return S_OK; +} + +STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value) +{ + if (index > sizeof(g_Methods) / sizeof(g_Methods[1])) + return E_INVALIDARG; + VariantClear((tagVARIANT *)value); + const CRarMethodItem &method = g_Methods[index]; + switch(propID) + { + case NMethodPropID::kID: + if ((value->bstrVal = ::SysAllocStringByteLen(method.ID, + sizeof(method.ID))) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kName: + if ((value->bstrVal = ::SysAllocString(method.UserName)) != 0) + value->vt = VT_BSTR; + return S_OK; + case NMethodPropID::kDecoder: + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)method.Decoder, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + return S_OK; +} diff --git a/7zip/Compress/Rar29/Original/archive.hpp b/7zip/Compress/Rar29/Original/archive.hpp new file mode 100755 index 00000000..c076b5b7 --- /dev/null +++ b/7zip/Compress/Rar29/Original/archive.hpp @@ -0,0 +1,128 @@ +#ifndef _RAR_ARCHIVE_ +#define _RAR_ARCHIVE_ + +class Pack; + +enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4}; + +class Archive:public File +{ + private: + bool IsSignature(byte *D); + void UpdateLatestTime(FileHeader *CurBlock); + void Protect(int RecSectors); + void ConvertNameCase(char *Name); + void ConvertNameCase(wchar *Name); + void ConvertUnknownHeader(); + bool AddArcComment(char *NameToShow); + int ReadOldHeader(); + void PrepareExtraTime(FileHeader *hd,EXTTIME_MODE etm,EXTTIME_MODE etc,EXTTIME_MODE eta,EXTTIME_MODE etarc,Array<byte> &TimeData); + +#if !defined(SHELL_EXT) && !defined(NOCRYPT) + CryptData HeadersCrypt; + byte HeadersSalt[SALT_SIZE]; +#endif +#ifndef SHELL_EXT + ComprDataIO SubDataIO; + byte SubDataSalt[SALT_SIZE]; +#endif + RAROptions *Cmd,DummyCmd; + + MarkHeader MarkHead; + OldMainHeader OldMhd; + + int RecoverySectors; + Int64 RecoveryPos; + + RarTime LatestTime; + int LastReadBlock; + int CurHeaderType; + + bool SilentOpen; + public: + Archive(RAROptions *InitCmd=NULL); + bool IsArchive(bool EnableBroken); + int SearchBlock(int BlockType); + int SearchSubBlock(const char *Type); + int ReadBlock(int BlockType); + void WriteBlock(int BlockType,BaseBlock *wb=NULL); + int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW); + void SetLhdSize(); + int ReadHeader(); + void CheckArc(bool EnableBroken); + void CheckOpen(char *Name,wchar *NameW=NULL); + bool WCheckOpen(char *Name,wchar *NameW=NULL); + bool TestLock(int Mode); + void MakeTemp(); + void CopyMainHeader(Archive &Src,bool CopySFX=true,char *NameToDisplay=NULL); + bool ProcessToFileHead(Archive &Src,bool LastBlockAdded, + Pack *Pack=NULL,const char *SkipName=NULL); + void TmpToArc(Archive &Src); + void CloseNew(int AdjustRecovery,bool CloseVolume); + void WriteEndBlock(bool CloseVolume); + void CopyFileRecord(Archive &Src); + void CopyArchiveData(Archive &Src); + bool GetComment(Array<byte> &CmtData); + void ViewComment(); + void ViewFileComment(); + void SetLatestTime(RarTime *NewTime); + void SeekToNext(); + bool CheckAccess(); + bool IsArcDir(); + bool IsArcLabel(); + void ConvertAttributes(); + int GetRecoverySize(bool Required); + void VolSubtractHeaderSize(int SubSize); + void AddSubData(byte *SrcData,int DataSize,File *SrcFile,char *Name,bool AllowSplit); + bool ReadSubData(Array<byte> *UnpData,File *DestFile); + int GetHeaderType() {return(CurHeaderType);}; + int ReadCommentData(Array<byte> &CmtData); + void WriteCommentData(byte *Data,int DataSize,bool FileComment); + RAROptions* GetRAROptions() {return(Cmd);} + void SetSilentOpen(bool Mode) {SilentOpen=Mode;} + + BaseBlock ShortBlock; + MainHeader NewMhd; + FileHeader NewLhd; + EndArcHeader EndArcHead; + SubBlockHeader SubBlockHead; + FileHeader SubHead; + CommentHeader CommHead; + ProtectHeader ProtectHead; + AVHeader AVHead; + SignHeader SignHead; + UnixOwnersHeader UOHead; + MacFInfoHeader MACHead; + EAHeader EAHead; + StreamHeader StreamHead; + + Int64 CurBlockPos; + Int64 NextBlockPos; + + bool OldFormat; + bool Solid; + bool Volume; + bool MainComment; + bool Locked; + bool Signed; + bool NotFirstVolume; + bool Protected; + bool Encrypted; + uint SFXSize; + bool BrokenFileHeader; + + bool Splitting; + + ushort HeaderCRC; + + Int64 VolWrite; + Int64 AddingFilesSize; + uint AddingHeadersSize; + + bool NewArchive; + + char FirstVolumeName[NM]; + wchar FirstVolumeNameW[NM]; +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/array.hpp b/7zip/Compress/Rar29/Original/array.hpp new file mode 100755 index 00000000..3afec70c --- /dev/null +++ b/7zip/Compress/Rar29/Original/array.hpp @@ -0,0 +1,121 @@ +#ifndef _RAR_ARRAY_ +#define _RAR_ARRAY_ + +extern ErrorHandler ErrHandler; + +template <class T> class Array +{ + private: + T *Buffer; + int BufSize; + int AllocSize; + public: + Array(); + Array(int Size); + ~Array(); + inline void CleanData(); + inline T& operator [](int Item); + inline int Size(); + void Add(int Items); + void Alloc(int Items); + void Reset(); + void operator = (Array<T> &Src); + void Push(T Item); +}; + +template <class T> void Array<T>::CleanData() +{ + Buffer=NULL; + BufSize=0; + AllocSize=0; +} + + +template <class T> Array<T>::Array() +{ + CleanData(); +} + + +template <class T> Array<T>::Array(int Size) +{ + Buffer=(T *)rarmalloc(sizeof(T)*Size); + if (Buffer==NULL && Size!=0) + ErrHandler.MemoryError(); + + AllocSize=BufSize=Size; +} + + +template <class T> Array<T>::~Array() +{ + if (Buffer!=NULL) + rarfree(Buffer); +} + + +template <class T> inline T& Array<T>::operator [](int Item) +{ + return(Buffer[Item]); +} + + +template <class T> inline int Array<T>::Size() +{ + return(BufSize); +} + + +template <class T> void Array<T>::Add(int Items) +{ + BufSize+=Items; + if (BufSize>AllocSize) + { + int Suggested=AllocSize+AllocSize/4+32; + int NewSize=Max(BufSize,Suggested); + + Buffer=(T *)rarrealloc(Buffer,NewSize*sizeof(T)); + if (Buffer==NULL) + ErrHandler.MemoryError(); + AllocSize=NewSize; + } +} + + +template <class T> void Array<T>::Alloc(int Items) +{ + if (Items>AllocSize) + Add(Items-BufSize); + else + BufSize=Items; +} + + +template <class T> void Array<T>::Reset() +{ + if (Buffer!=NULL) + { + rarfree(Buffer); + Buffer=NULL; + } + BufSize=0; + AllocSize=0; +} + + +template <class T> void Array<T>::operator =(Array<T> &Src) +{ + Reset(); + Alloc(Src.BufSize); + if (Src.BufSize!=0) + memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T)); +} + + +template <class T> void Array<T>::Push(T Item) +{ + Add(1); + (*this)[Size()-1]=Item; +} + +#endif diff --git a/7zip/Compress/Rar29/Original/cmddata.hpp b/7zip/Compress/Rar29/Original/cmddata.hpp new file mode 100755 index 00000000..08b92c11 --- /dev/null +++ b/7zip/Compress/Rar29/Original/cmddata.hpp @@ -0,0 +1,56 @@ +#ifndef _RAR_CMDDATA_ +#define _RAR_CMDDATA_ + +#define DefaultStoreList "ace;arj;bz2;cab;gz;jpeg;jpg;lha;lzh;mp3;rar;zip;taz;tgz;z" + +class CommandData:public RAROptions +{ + private: + void ProcessSwitchesString(char *Str); + void ProcessSwitch(char *Switch); + void BadSwitch(char *Switch); + bool ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode); + uint GetExclAttr(char *Str); + + bool FileLists; + bool NoMoreSwitches; + bool TimeConverted; + bool BareOutput; + public: + CommandData(); + ~CommandData(); + void Init(); + void Close(); + void ParseArg(char *Arg,wchar *ArgW); + void ParseDone(); + void ParseEnvVar(); + void ReadConfig(int argc,char *argv[]); + bool IsConfigEnabled(int argc,char *argv[]); + void OutTitle(); + void OutHelp(); + bool IsSwitch(int Ch); + bool ExclCheck(char *CheckName,bool CheckFullPath); + bool StoreCheck(char *CheckName); + bool TimeCheck(RarTime &ft); + int IsProcessFile(FileHeader &NewLhd,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH); + void ProcessCommand(); + void AddArcName(char *Name,wchar *NameW); + bool GetArcName(char *Name,wchar *NameW,int MaxSize); + bool CheckWinSize(); + + int GetRecoverySize(char *Str,int DefSize); + + char Command[NM+16]; + wchar CommandW[NM+16]; + + char ArcName[NM]; + wchar ArcNameW[NM]; + + StringList *FileArgs; + StringList *ExclArgs; + StringList *InclArgs; + StringList *ArcNames; + StringList *StoreArgs; +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/coder.cpp b/7zip/Compress/Rar29/Original/coder.cpp new file mode 100755 index 00000000..cb6a8836 --- /dev/null +++ b/7zip/Compress/Rar29/Original/coder.cpp @@ -0,0 +1,47 @@ + + +inline unsigned int RangeCoder::GetChar() +{ + return(UnpackRead->GetChar()); +} + + +void RangeCoder::InitDecoder(Unpack *UnpackRead) +{ + RangeCoder::UnpackRead=UnpackRead; + + low=code=0; + range=uint(-1); + for (int i=0;i < 4;i++) + code=(code << 8) | GetChar(); +} + + +#define ARI_DEC_NORMALIZE(code,low,range,read) \ +{ \ + while ((low^(low+range))<TOP || range<BOT && ((range=-low&(BOT-1)),1)) \ + { \ + code=(code << 8) | read->GetChar(); \ + range <<= 8; \ + low <<= 8; \ + } \ +} + + +inline int RangeCoder::GetCurrentCount() +{ + return (code-low)/(range /= SubRange.scale); +} + + +inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT) +{ + return (code-low)/(range >>= SHIFT); +} + + +inline void RangeCoder::Decode() +{ + low += range*SubRange.LowCount; + range *= SubRange.HighCount-SubRange.LowCount; +} diff --git a/7zip/Compress/Rar29/Original/coder.hpp b/7zip/Compress/Rar29/Original/coder.hpp new file mode 100755 index 00000000..f09f911c --- /dev/null +++ b/7zip/Compress/Rar29/Original/coder.hpp @@ -0,0 +1,24 @@ +/**************************************************************************** + * Contents: 'Carryless rangecoder' by Dmitry Subbotin * + ****************************************************************************/ + +const uint TOP=1 << 24, BOT=1 << 15; + +class RangeCoder +{ + public: + void InitDecoder(Unpack *UnpackRead); + inline int GetCurrentCount(); + inline uint GetCurrentShiftCount(uint SHIFT); + inline void Decode(); + inline void PutChar(unsigned int c); + inline unsigned int GetChar(); + + uint low, code, range; + struct SUBRANGE + { + uint LowCount, HighCount, scale; + } SubRange; + + Unpack *UnpackRead; +}; diff --git a/7zip/Compress/Rar29/Original/compress.hpp b/7zip/Compress/Rar29/Original/compress.hpp new file mode 100755 index 00000000..2ba7b23e --- /dev/null +++ b/7zip/Compress/Rar29/Original/compress.hpp @@ -0,0 +1,36 @@ +#ifndef _RAR_COMPRESS_ +#define _RAR_COMPRESS_ + +class ComprDataIO; +class PackingFileTable; + +#define CODEBUFSIZE 0x4000 +#define MAXWINSIZE 0x400000 +#define MAXWINMASK (MAXWINSIZE-1) + +#define LOW_DIST_REP_COUNT 16 + +#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */ +#define DC 60 +#define LDC 17 +#define RC 28 +#define HUFF_TABLE_SIZE (NC+DC+RC+LDC) +#define BC 20 + +#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */ +#define DC20 48 +#define RC20 28 +#define BC20 19 +#define MC20 257 + +enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ, + CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA}; + + +enum FilterType { + FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9, + FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA, + FILTER_ITANIUM, FILTER_E8E9V2 +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/consio.hpp b/7zip/Compress/Rar29/Original/consio.hpp new file mode 100755 index 00000000..780ae7f3 --- /dev/null +++ b/7zip/Compress/Rar29/Original/consio.hpp @@ -0,0 +1,42 @@ +#ifndef _RAR_CONSIO_ +#define _RAR_CONSIO_ + +enum {ALARM_SOUND,ERROR_SOUND,QUESTION_SOUND}; + +enum PASSWORD_TYPE {PASSWORD_GLOBAL,PASSWORD_FILE,PASSWORD_ARCHIVE}; + +void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound); + +#ifndef SILENT +void mprintf(const char *fmt,...); +void eprintf(const char *fmt,...); +void Alarm(); +void GetPasswordText(char *Str,int MaxLength); +unsigned int GetKey(); +bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength); +int Ask(const char *AskStr); +#endif + +int KbdAnsi(char *Addr,int Size); +void OutComment(char *Comment,int Size); + +#ifdef SILENT +#ifdef __GNUC__ + #define mprintf(args...) + #define eprintf(args...) +#else + inline void mprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {} + inline void eprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {} + inline void mprintf(const char *fmt,int b) {} + inline void eprintf(const char *fmt,int b) {} + inline void mprintf(const char *fmt,const char *a,int b) {} + inline void eprintf(const char *fmt,const char *a,int b) {} +#endif +inline void Alarm() {} +inline void GetPasswordText(char *Str,int MaxLength) {} +inline unsigned int GetKey() {return(0);} +inline bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength) {return(false);} +inline int Ask(const char *AskStr) {return(0);} +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/crc.cpp b/7zip/Compress/Rar29/Original/crc.cpp new file mode 100755 index 00000000..c19f8595 --- /dev/null +++ b/7zip/Compress/Rar29/Original/crc.cpp @@ -0,0 +1,61 @@ +#include "rar.hpp" + +uint CRCTab[256]; + +void InitCRC() +{ + for (int I=0;I<256;I++) + { + uint C=I; + for (int J=0;J<8;J++) + C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1); + CRCTab[I]=C; + } +} + + +uint CRC(uint StartCRC,const void *Addr,uint Size) +{ + if (CRCTab[1]==0) + InitCRC(); + byte *Data=(byte *)Addr; +#if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) + while (Size>0 && ((long)Data & 7)) + { + StartCRC=CRCTab[(byte)(StartCRC^Data[0])]^(StartCRC>>8); + Size--; + Data++; + } + while (Size>=8) + { + StartCRC^=*(uint32 *)Data; + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC^=*(uint32 *)(Data+4); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); + Data+=8; + Size-=8; + } +#endif + for (int I=0;I<Size;I++) + StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8); + return(StartCRC); +} + +#ifndef SFX_MODULE +ushort OldCRC(ushort StartCRC,const void *Addr,uint Size) +{ + byte *Data=(byte *)Addr; + for (int I=0;I<Size;I++) + { + StartCRC=(StartCRC+Data[I])&0xffff; + StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff; + } + return(StartCRC); +} +#endif diff --git a/7zip/Compress/Rar29/Original/crc.hpp b/7zip/Compress/Rar29/Original/crc.hpp new file mode 100755 index 00000000..47ee7e23 --- /dev/null +++ b/7zip/Compress/Rar29/Original/crc.hpp @@ -0,0 +1,10 @@ +#ifndef _RAR_CRC_ +#define _RAR_CRC_ + +extern uint CRCTab[256]; + +void InitCRC(); +uint CRC(uint StartCRC,const void *Addr,uint Size); +ushort OldCRC(ushort StartCRC,const void *Addr,uint Size); + +#endif diff --git a/7zip/Compress/Rar29/Original/crypt.hpp b/7zip/Compress/Rar29/Original/crypt.hpp new file mode 100755 index 00000000..809d76a5 --- /dev/null +++ b/7zip/Compress/Rar29/Original/crypt.hpp @@ -0,0 +1,60 @@ +#ifndef _RAR_CRYPT_ +#define _RAR_CRYPT_ + +enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 }; + +struct CryptKeyCacheItem +{ +#ifndef _SFX_RTL_ + CryptKeyCacheItem() + { + *Password=0; + } + + ~CryptKeyCacheItem() + { + memset(AESKey,0,sizeof(AESKey)); + memset(AESInit,0,sizeof(AESInit)); + memset(Password,0,sizeof(Password)); + } +#endif + byte AESKey[16],AESInit[16]; + char Password[MAXPASSWORD]; + bool SaltPresent; + byte Salt[SALT_SIZE]; +}; + +class CryptData +{ + private: + void Encode13(byte *Data,uint Count); + void Decode13(byte *Data,uint Count); + void Crypt15(byte *Data,uint Count); + void UpdKeys(byte *Buf); + void Swap(byte *Ch1,byte *Ch2); + void SetOldKeys(char *Password); + + Rijndael rin; + + byte SubstTable[256]; + uint Key[4]; + ushort OldKey[4]; + byte PN1,PN2,PN3; + + byte AESKey[16],AESInit[16]; + + static CryptKeyCacheItem Cache[4]; + static int CachePos; + public: + void SetCryptKeys(char *Password,byte *Salt,bool Encrypt,bool OldOnly=false); + void SetAV15Encryption(); + void SetCmt13Encryption(); + void EncryptBlock20(byte *Buf); + void DecryptBlock20(byte *Buf); + void EncryptBlock(byte *Buf,int Size); + void DecryptBlock(byte *Buf,int Size); + void Crypt(byte *Data,uint Count,int Method); + static void SetSalt(byte *Salt,int SaltSize); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/encname.hpp b/7zip/Compress/Rar29/Original/encname.hpp new file mode 100755 index 00000000..586f4216 --- /dev/null +++ b/7zip/Compress/Rar29/Original/encname.hpp @@ -0,0 +1,20 @@ +#ifndef _RAR_ENCNAME_ +#define _RAR_ENCNAME_ + +class EncodeFileName +{ + private: + void AddFlags(int Value); + + byte *EncName; + byte Flags; + int FlagBits; + int FlagsPos; + int DestSize; + public: + EncodeFileName(); + int Encode(char *Name,wchar *NameW,byte *EncName); + void Decode(char *Name,byte *EncName,int EncSize,wchar *NameW,int MaxDecSize); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/errhnd.cpp b/7zip/Compress/Rar29/Original/errhnd.cpp new file mode 100755 index 00000000..6e162217 --- /dev/null +++ b/7zip/Compress/Rar29/Original/errhnd.cpp @@ -0,0 +1,356 @@ +#include "rar.hpp" + + +static bool UserBreak; + +ErrorHandler::ErrorHandler() +{ + Clean(); +} + + +void ErrorHandler::Clean() +{ + ExitCode=SUCCESS; + ErrCount=0; + EnableBreak=true; + Silent=false; + DoShutdown=false; +} + + +void ErrorHandler::MemoryError() +{ + MemoryErrorMsg(); + Throw(MEMORY_ERROR); +} + + +void ErrorHandler::OpenError(const char *FileName) +{ +#ifndef SILENT + OpenErrorMsg(FileName); + Throw(OPEN_ERROR); +#endif +} + + +void ErrorHandler::CloseError(const char *FileName) +{ +#ifndef SILENT + if (!UserBreak) + { + ErrMsg(NULL,St(MErrFClose),FileName); + SysErrMsg(); + } +#endif +#if !defined(SILENT) || defined(RARDLL) + Throw(FATAL_ERROR); +#endif +} + + +void ErrorHandler::ReadError(const char *FileName) +{ +#ifndef SILENT + ReadErrorMsg(NULL,FileName); +#endif +#if !defined(SILENT) || defined(RARDLL) + Throw(FATAL_ERROR); +#endif +} + + +bool ErrorHandler::AskRepeatRead(const char *FileName) +{ +#if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE) + if (!Silent) + { + mprintf("\n"); + Log(NULL,St(MErrRead),FileName); + return(Ask(St(MRetryAbort))==1); + } +#endif + return(false); +} + + +void ErrorHandler::WriteError(const char *ArcName,const char *FileName) +{ +#ifndef SILENT + WriteErrorMsg(ArcName,FileName); +#endif +#if !defined(SILENT) || defined(RARDLL) + Throw(WRITE_ERROR); +#endif +} + + +#ifdef _WIN_32 +void ErrorHandler::WriteErrorFAT(const char *FileName) +{ +#if !defined(SILENT) && !defined(SFX_MODULE) + SysErrMsg(); + ErrMsg(NULL,St(MNTFSRequired),FileName); +#endif +#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL) + Throw(WRITE_ERROR); +#endif +} +#endif + + +bool ErrorHandler::AskRepeatWrite(const char *FileName) +{ +#if !defined(SILENT) && !defined(_WIN_CE) + if (!Silent) + { + mprintf("\n"); + Log(NULL,St(MErrWrite),FileName); + return(Ask(St(MRetryAbort))==1); + } +#endif + return(false); +} + + +void ErrorHandler::SeekError(const char *FileName) +{ +#ifndef SILENT + if (!UserBreak) + { + ErrMsg(NULL,St(MErrSeek),FileName); + SysErrMsg(); + } +#endif +#if !defined(SILENT) || defined(RARDLL) + Throw(FATAL_ERROR); +#endif +} + + +void ErrorHandler::MemoryErrorMsg() +{ +#ifndef SILENT + ErrMsg(NULL,St(MErrOutMem)); +#endif +} + + +void ErrorHandler::OpenErrorMsg(const char *FileName) +{ + OpenErrorMsg(NULL,FileName); +} + + +void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName) +{ +#ifndef SILENT + Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName); + Alarm(); + SysErrMsg(); +#endif +} + + +void ErrorHandler::CreateErrorMsg(const char *FileName) +{ + CreateErrorMsg(NULL,FileName); +} + + +void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName) +{ +#ifndef SILENT + Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName); + Alarm(); +#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAXPATH) + if (GetLastError()==ERROR_PATH_NOT_FOUND) + { + int NameLength=strlen(FileName); + if (!IsFullPath(FileName)) + { + char CurDir[NM]; + GetCurrentDirectory(sizeof(CurDir),CurDir); + NameLength+=strlen(CurDir)+1; + } + if (NameLength>MAXPATH) + { + Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAXPATH); + } + } +#endif + SysErrMsg(); +#endif +} + + +void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName) +{ +#ifndef SILENT + ErrMsg(ArcName,St(MErrRead),FileName); + SysErrMsg(); +#endif +} + + +void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName) +{ +#ifndef SILENT + ErrMsg(ArcName,St(MErrWrite),FileName); + SysErrMsg(); +#endif +} + + +void ErrorHandler::Exit(int ExitCode) +{ +#ifndef SFX_MODULE + Alarm(); +#endif + Throw(ExitCode); +} + + +#ifndef GUI +void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...) +{ + safebuf char Msg[NM+1024]; + va_list argptr; + va_start(argptr,fmt); + vsprintf(Msg,fmt,argptr); + va_end(argptr); +#ifdef _WIN_32 + if (UserBreak) + Sleep(5000); +#endif + Alarm(); + if (*Msg) + { + Log(ArcName,"\n%s",Msg); + mprintf("\n%s\n",St(MProgAborted)); + } +} +#endif + + +void ErrorHandler::SetErrorCode(int Code) +{ + switch(Code) + { + case WARNING: + case USER_BREAK: + if (ExitCode==SUCCESS) + ExitCode=Code; + break; + case FATAL_ERROR: + if (ExitCode==SUCCESS || ExitCode==WARNING) + ExitCode=FATAL_ERROR; + break; + default: + ExitCode=Code; + break; + } + ErrCount++; +} + + +#if !defined(GUI) && !defined(_SFX_RTL_) +#ifdef _WIN_32 +BOOL __stdcall ProcessSignal(DWORD SigType) +#else +#if defined(__sun) +extern "C" +#endif +void _stdfunction ProcessSignal(int SigType) +#endif +{ +#ifdef _WIN_32 + if (SigType==CTRL_LOGOFF_EVENT) + return(TRUE); +#endif + UserBreak=true; + mprintf(St(MBreak)); + for (int I=0; + // Igor Pavlov + // !File::RemoveCreated() && + I<3;I++) + { +#ifdef _WIN_32 + Sleep(100); +#endif + } +#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE) + ExtRes.UnloadDLL(); +#endif + exit(USER_BREAK); +#ifdef _WIN_32 + return(TRUE); +#endif +} +#endif + + +void ErrorHandler::SetSignalHandlers(bool Enable) +{ + EnableBreak=Enable; +#if !defined(GUI) && !defined(_SFX_RTL_) +#ifdef _WIN_32 + SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE); +// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN); +#else + signal(SIGINT,Enable ? ProcessSignal:SIG_IGN); + signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN); +#endif +#endif +} + + +void ErrorHandler::Throw(int Code) +{ + if (Code==USER_BREAK && !EnableBreak) + return; + ErrHandler.SetErrorCode(Code); +#ifdef ALLOW_EXCEPTIONS + throw Code; +#else + // Igor Pavlov + // File::RemoveCreated(); + exit(Code); +#endif +} + + +void ErrorHandler::SysErrMsg() +{ +#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SILENT) + #define STRCHR strchr + #define ERRCHAR char + ERRCHAR *lpMsgBuf=NULL; + int ErrType=GetLastError(); + if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf,0,NULL)) + { + ERRCHAR *CurMsg=lpMsgBuf; + while (CurMsg!=NULL) + { + while (*CurMsg=='\r' || *CurMsg=='\n') + CurMsg++; + if (*CurMsg==0) + break; + ERRCHAR *EndMsg=STRCHR(CurMsg,'\r'); + if (EndMsg==NULL) + EndMsg=STRCHR(CurMsg,'\n'); + if (EndMsg!=NULL) + { + *EndMsg=0; + EndMsg++; + } + Log(NULL,"\n%s",CurMsg); + CurMsg=EndMsg; + } + } + LocalFree( lpMsgBuf ); +#endif +} diff --git a/7zip/Compress/Rar29/Original/errhnd.hpp b/7zip/Compress/Rar29/Original/errhnd.hpp new file mode 100755 index 00000000..9e276222 --- /dev/null +++ b/7zip/Compress/Rar29/Original/errhnd.hpp @@ -0,0 +1,61 @@ +#ifndef _RAR_ERRHANDLER_ +#define _RAR_ERRHANDLER_ + +#if (defined(GUI) || !defined(_WIN_32)) && !defined(SFX_MODULE) && !defined(_WIN_CE) || defined(RARDLL) +#define ALLOW_EXCEPTIONS +#endif + + + +#define rarmalloc malloc +#define rarcalloc calloc +#define rarrealloc realloc +#define rarfree free +#define rarstrdup strdup + + + +enum { SUCCESS,WARNING,FATAL_ERROR,CRC_ERROR,LOCK_ERROR,WRITE_ERROR, + OPEN_ERROR,USER_ERROR,MEMORY_ERROR,CREATE_ERROR,USER_BREAK=255}; + +class ErrorHandler +{ + private: + void ErrMsg(const char *ArcName,const char *fmt,...); + + int ExitCode; + int ErrCount; + bool EnableBreak; + bool Silent; + bool DoShutdown; + public: + ErrorHandler(); + void Clean(); + void MemoryError(); + void OpenError(const char *FileName); + void CloseError(const char *FileName); + void ReadError(const char *FileName); + bool AskRepeatRead(const char *FileName); + void WriteError(const char *ArcName,const char *FileName); + void WriteErrorFAT(const char *FileName); + bool AskRepeatWrite(const char *FileName); + void SeekError(const char *FileName); + void MemoryErrorMsg(); + void OpenErrorMsg(const char *FileName); + void OpenErrorMsg(const char *ArcName,const char *FileName); + void CreateErrorMsg(const char *FileName); + void CreateErrorMsg(const char *ArcName,const char *FileName); + void ReadErrorMsg(const char *ArcName,const char *FileName); + void WriteErrorMsg(const char *ArcName,const char *FileName); + void Exit(int ExitCode); + void SetErrorCode(int Code); + int GetErrorCode() {return(ExitCode);} + int GetErrorCount() {return(ErrCount);} + void SetSignalHandlers(bool Enable); + void Throw(int Code); + void SetSilent(bool Mode) {Silent=Mode;}; + void SetShutdown(bool Mode) {DoShutdown=Mode;}; + void SysErrMsg(); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/extinfo.hpp b/7zip/Compress/Rar29/Original/extinfo.hpp new file mode 100755 index 00000000..db7cea53 --- /dev/null +++ b/7zip/Compress/Rar29/Original/extinfo.hpp @@ -0,0 +1,8 @@ +#ifndef _RAR_EXTINFO_ +#define _RAR_EXTINFO_ + + +void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW); +void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW); + +#endif diff --git a/7zip/Compress/Rar29/Original/extract.hpp b/7zip/Compress/Rar29/Original/extract.hpp new file mode 100755 index 00000000..b78c988d --- /dev/null +++ b/7zip/Compress/Rar29/Original/extract.hpp @@ -0,0 +1,40 @@ +#ifndef _RAR_EXTRACT_ +#define _RAR_EXTRACT_ + +enum EXTRACT_ARC_CODE {EXTRACT_ARC_NEXT,EXTRACT_ARC_REPEAT}; + +class CmdExtract +{ + private: + ComprDataIO DataIO; + Unpack *Unp; + long TotalFileCount; + + long FileCount; + long MatchedArgs; + bool FirstFile; + bool AllMatchesExact; + bool ReconstructDone; + + char ArcName[NM]; + wchar ArcNameW[NM]; + + char Password[MAXPASSWORD]; + bool PasswordAll; + bool PrevExtracted; + bool SignatureFound; + char DestFileName[NM]; + wchar DestFileNameW[NM]; + bool PasswordCancelled; + public: + CmdExtract(); + ~CmdExtract(); + void DoExtract(CommandData *Cmd); + void ExtractArchiveInit(CommandData *Cmd,Archive &Arc); + EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd); + bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize, + bool &Repeat); + static void UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/filcreat.hpp b/7zip/Compress/Rar29/Original/filcreat.hpp new file mode 100755 index 00000000..fa1fddd0 --- /dev/null +++ b/7zip/Compress/Rar29/Original/filcreat.hpp @@ -0,0 +1,12 @@ +#ifndef _RAR_FILECREATE_ +#define _RAR_FILECREATE_ + +bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW, + OVERWRITE_MODE Mode,bool *UserReject,Int64 FileSize=INT64ERR, + uint FileTime=0); + +#if defined(_WIN_32) && !defined(_WIN_CE) +bool UpdateExistingShortName(char *Name,wchar *NameW); +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/file.hpp b/7zip/Compress/Rar29/Original/file.hpp new file mode 100755 index 00000000..afa9529c --- /dev/null +++ b/7zip/Compress/Rar29/Original/file.hpp @@ -0,0 +1,100 @@ +#ifndef _RAR_FILE_ +#define _RAR_FILE_ + +#ifdef _WIN_32 +typedef HANDLE FileHandle; +#define BAD_HANDLE INVALID_HANDLE_VALUE +#else +typedef FILE* FileHandle; +#define BAD_HANDLE NULL +#endif + +class RAROptions; + +enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD,FILE_HANDLEERR}; + +enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR}; + +struct FileStat +{ + uint FileAttr; + uint FileTime; + Int64 FileSize; + bool IsDir; +}; + + +class File +{ + private: + void AddFileToList(FileHandle hFile); + + FileHandle hFile; + bool LastWrite; + FILE_HANDLETYPE HandleType; + bool SkipClose; + bool IgnoreReadErrors; + bool NewFile; + bool AllowDelete; + bool AllowExceptions; +#ifdef _WIN_32 + bool NoSequentialRead; +#endif + protected: + bool OpenShared; + public: + char FileName[NM]; + wchar FileNameW[NM]; + + FILE_ERRORTYPE ErrorType; + + uint CloseCount; + public: + File(); + virtual ~File(); + void operator = (File &SrcFile); + bool Open(const char *Name,const wchar *NameW=NULL,bool OpenShared=false,bool Update=false); + void TOpen(const char *Name,const wchar *NameW=NULL); + bool WOpen(const char *Name,const wchar *NameW=NULL); + bool Create(const char *Name,const wchar *NameW=NULL); + void TCreate(const char *Name,const wchar *NameW=NULL); + bool WCreate(const char *Name,const wchar *NameW=NULL); + bool Close(); + void Flush(); + bool Delete(); + bool Rename(const char *NewName); + void Write(const void *Data,int Size); + int Read(void *Data,int Size); + int DirectRead(void *Data,int Size); + void Seek(Int64 Offset,int Method); + bool RawSeek(Int64 Offset,int Method); + Int64 Tell(); + void Prealloc(Int64 Size); + byte GetByte(); + void PutByte(byte Byte); + bool Truncate(); + void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL); + void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL); + static void SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta); + void SetOpenFileStat(RarTime *ftm,RarTime *ftc,RarTime *fta); + void SetCloseFileStat(RarTime *ftm,RarTime *fta,uint FileAttr); + void GetOpenFileTime(RarTime *ft); + bool IsOpened() {return(hFile!=BAD_HANDLE);}; + Int64 FileLength(); + void SetHandleType(FILE_HANDLETYPE Type); + FILE_HANDLETYPE GetHandleType() {return(HandleType);}; + bool IsDevice(); + void fprintf(const char *fmt,...); + static bool RemoveCreated(); + FileHandle GetHandle() {return(hFile);}; + void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;}; + char *GetName() {return(FileName);} + long Copy(File &Dest,Int64 Length=INT64ERR); + void SetAllowDelete(bool Allow) {AllowDelete=Allow;} + void SetExceptions(bool Allow) {AllowExceptions=Allow;} +#ifdef _WIN_32 + void RemoveSequentialFlag() {NoSequentialRead=true;} +#endif +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/filefn.hpp b/7zip/Compress/Rar29/Original/filefn.hpp new file mode 100755 index 00000000..3ad31b5e --- /dev/null +++ b/7zip/Compress/Rar29/Original/filefn.hpp @@ -0,0 +1,39 @@ +#ifndef _RAR_FILEFN_ +#define _RAR_FILEFN_ + +enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH}; + +MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr); +void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName); +void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta); +bool IsRemovable(const char *Name); +Int64 GetFreeDisk(const char *Name); +bool FileExist(const char *Name,const wchar *NameW=NULL); +bool WildFileExist(const char *Name,const wchar *NameW=NULL); +bool IsDir(uint Attr); +bool IsUnreadable(uint Attr); +bool IsLabel(uint Attr); +bool IsLink(uint Attr); +void SetSFXMode(const char *FileName); +void EraseDiskContents(const char *FileName); +bool IsDeleteAllowed(uint FileAttr); +void PrepareToDelete(const char *Name,const wchar *NameW=NULL); +uint GetFileAttr(const char *Name,const wchar *NameW=NULL); +bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr); +void ConvertNameToFull(const char *Src,char *Dest); +void ConvertNameToFull(const wchar *Src,wchar *Dest); +char* MkTemp(char *Name); + + +uint CalcFileCRC(File *SrcFile,Int64 Size=INT64ERR); +bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW); +bool DelFile(const char *Name); +bool DelFile(const char *Name,const wchar *NameW); +bool DelDir(const char *Name); +bool DelDir(const char *Name,const wchar *NameW); + +#if defined(_WIN_32) && !defined(_WIN_CE) +bool SetFileCompression(char *Name,wchar *NameW,bool State); +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/filestr.hpp b/7zip/Compress/Rar29/Original/filestr.hpp new file mode 100755 index 00000000..b2bcbe0e --- /dev/null +++ b/7zip/Compress/Rar29/Original/filestr.hpp @@ -0,0 +1,8 @@ +#ifndef _RAR_FILESTR_ +#define _RAR_FILESTR_ + +bool ReadTextFile(char *Name,StringList *List,bool Config, + bool AbortOnError=false,bool ConvertToAnsi=false, + bool Unquote=false,bool SkipComments=false); + +#endif diff --git a/7zip/Compress/Rar29/Original/find.hpp b/7zip/Compress/Rar29/Original/find.hpp new file mode 100755 index 00000000..81548199 --- /dev/null +++ b/7zip/Compress/Rar29/Original/find.hpp @@ -0,0 +1,48 @@ +#ifndef _RAR_FINDDATA_ +#define _RAR_FINDDATA_ + +struct FindData +{ + char Name[NM]; + wchar NameW[NM]; + Int64 Size; + uint FileAttr; + uint FileTime; + bool IsDir; + RarTime mtime; + RarTime ctime; + RarTime atime; +#ifdef _WIN_32 + char ShortName[NM]; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; +#endif + bool Error; +}; + +class FindFile +{ + private: +#ifdef _WIN_32 + static HANDLE Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd); +#endif + + char FindMask[NM]; + wchar FindMaskW[NM]; + int FirstCall; +#ifdef _WIN_32 + HANDLE hFind; +#else + DIR *dirp; +#endif + public: + FindFile(); + ~FindFile(); + void SetMask(const char *FindMask); + void SetMaskW(const wchar *FindMaskW); + bool Next(struct FindData *fd,bool GetSymLink=false); + static bool FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink=false); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/getbits.cpp b/7zip/Compress/Rar29/Original/getbits.cpp new file mode 100755 index 00000000..71ecfc87 --- /dev/null +++ b/7zip/Compress/Rar29/Original/getbits.cpp @@ -0,0 +1,24 @@ +#include "rar.hpp" + +BitInput::BitInput() +{ + InBuf=new byte[MAX_SIZE]; +} + + +BitInput::~BitInput() +{ + delete[] InBuf; +} + + +void BitInput::faddbits(int Bits) +{ + addbits(Bits); +} + + +unsigned int BitInput::fgetbits() +{ + return(getbits()); +} diff --git a/7zip/Compress/Rar29/Original/getbits.hpp b/7zip/Compress/Rar29/Original/getbits.hpp new file mode 100755 index 00000000..8819f53a --- /dev/null +++ b/7zip/Compress/Rar29/Original/getbits.hpp @@ -0,0 +1,37 @@ +#ifndef _RAR_GETBITS_ +#define _RAR_GETBITS_ + +class BitInput +{ + public: + enum BufferSize {MAX_SIZE=0x8000}; + protected: + int InAddr,InBit; + public: + BitInput(); + ~BitInput(); + + byte *InBuf; + + void InitBitInput() + { + InAddr=InBit=0; + } + void addbits(int Bits) + { + Bits+=InBit; + InAddr+=Bits>>3; + InBit=Bits&7; + } + unsigned int getbits() + { + unsigned int BitField=(uint)InBuf[InAddr] << 16; + BitField|=(uint)InBuf[InAddr+1] << 8; + BitField|=(uint)InBuf[InAddr+2]; + BitField >>= (8-InBit); + return(BitField & 0xffff); + } + void faddbits(int Bits); + unsigned int fgetbits(); +}; +#endif diff --git a/7zip/Compress/Rar29/Original/global.hpp b/7zip/Compress/Rar29/Original/global.hpp new file mode 100755 index 00000000..35c6cf91 --- /dev/null +++ b/7zip/Compress/Rar29/Original/global.hpp @@ -0,0 +1,14 @@ +#ifndef _RAR_GLOBAL_ +#define _RAR_GLOBAL_ + +#ifdef INCLUDEGLOBAL + #define EXTVAR +#else + #define EXTVAR extern +#endif + +EXTVAR ErrorHandler ErrHandler; + + + +#endif diff --git a/7zip/Compress/Rar29/Original/headers.hpp b/7zip/Compress/Rar29/Original/headers.hpp new file mode 100755 index 00000000..f719a7ec --- /dev/null +++ b/7zip/Compress/Rar29/Original/headers.hpp @@ -0,0 +1,304 @@ +#ifndef _RAR_HEADERS_ +#define _RAR_HEADERS_ + +#define SIZEOF_MARKHEAD 7 +#define SIZEOF_OLDMHD 7 +#define SIZEOF_NEWMHD 13 +#define SIZEOF_OLDLHD 21 +#define SIZEOF_NEWLHD 32 +#define SIZEOF_SHORTBLOCKHEAD 7 +#define SIZEOF_LONGBLOCKHEAD 11 +#define SIZEOF_SUBBLOCKHEAD 14 +#define SIZEOF_COMMHEAD 13 +#define SIZEOF_PROTECTHEAD 26 +#define SIZEOF_AVHEAD 14 +#define SIZEOF_SIGNHEAD 15 +#define SIZEOF_UOHEAD 18 +#define SIZEOF_MACHEAD 22 +#define SIZEOF_EAHEAD 24 +#define SIZEOF_BEEAHEAD 24 +#define SIZEOF_STREAMHEAD 26 + +#define PACK_VER 29 +#define PACK_CRYPT_VER 29 +#define UNP_VER 29 +#define CRYPT_VER 29 +#define AV_VER 20 +#define PROTECT_VER 20 + +#define MHD_VOLUME 0x0001 +#define MHD_COMMENT 0x0002 +#define MHD_LOCK 0x0004 +#define MHD_SOLID 0x0008 +#define MHD_PACK_COMMENT 0x0010 +#define MHD_NEWNUMBERING 0x0010 +#define MHD_AV 0x0020 +#define MHD_PROTECT 0x0040 +#define MHD_PASSWORD 0x0080 +#define MHD_FIRSTVOLUME 0x0100 + +#define LHD_SPLIT_BEFORE 0x0001 +#define LHD_SPLIT_AFTER 0x0002 +#define LHD_PASSWORD 0x0004 +#define LHD_COMMENT 0x0008 +#define LHD_SOLID 0x0010 + +#define LHD_WINDOWMASK 0x00e0 +#define LHD_WINDOW64 0x0000 +#define LHD_WINDOW128 0x0020 +#define LHD_WINDOW256 0x0040 +#define LHD_WINDOW512 0x0060 +#define LHD_WINDOW1024 0x0080 +#define LHD_WINDOW2048 0x00a0 +#define LHD_WINDOW4096 0x00c0 +#define LHD_DIRECTORY 0x00e0 + +#define LHD_LARGE 0x0100 +#define LHD_UNICODE 0x0200 +#define LHD_SALT 0x0400 +#define LHD_VERSION 0x0800 +#define LHD_EXTTIME 0x1000 +#define LHD_EXTFLAGS 0x2000 + +#define SKIP_IF_UNKNOWN 0x4000 +#define LONG_BLOCK 0x8000 + +#define EARC_NEXT_VOLUME 0x0001 +#define EARC_DATACRC 0x0002 +#define EARC_REVSPACE 0x0004 +#define EARC_VOLNUMBER 0x0008 + +enum HEADER_TYPE { + MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76, + SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a, + ENDARC_HEAD=0x7b +}; + +enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103, + NTACL_HEAD=0x104,STREAM_HEAD=0x105 }; + +enum HOST_SYSTEM { + HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4, + HOST_BEOS=5,HOST_MAX +}; + +#define SUBHEAD_TYPE_CMT "CMT" +#define SUBHEAD_TYPE_ACL "ACL" +#define SUBHEAD_TYPE_STREAM "STM" +#define SUBHEAD_TYPE_UOWNER "UOW" +#define SUBHEAD_TYPE_AV "AV" +#define SUBHEAD_TYPE_RR "RR" +#define SUBHEAD_TYPE_OS2EA "EA2" +#define SUBHEAD_TYPE_BEOSEA "EABE" + +/* new file inherits a subblock when updating a host file */ +#define SUBHEAD_FLAGS_INHERITED 0x80000000 + +#define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001 + +struct OldMainHeader +{ + byte Mark[4]; + ushort HeadSize; + byte Flags; +}; + + +struct OldFileHeader +{ + uint PackSize; + uint UnpSize; + ushort FileCRC; + ushort HeadSize; + uint FileTime; + byte FileAttr; + byte Flags; + byte UnpVer; + byte NameSize; + byte Method; +}; + + +struct MarkHeader +{ + byte Mark[7]; +}; + + +struct BaseBlock +{ + ushort HeadCRC; + HEADER_TYPE HeadType;//byte + ushort Flags; + ushort HeadSize; + + bool IsSubBlock() + { + if (HeadType==SUB_HEAD) + return(true); + if (HeadType==NEWSUB_HEAD && (Flags & LHD_SOLID)!=0) + return(true); + return(false); + } +}; + +struct BlockHeader:BaseBlock +{ + union { + uint DataSize; + uint PackSize; + }; +}; + + +struct MainHeader:BlockHeader +{ + ushort HighPosAV; + uint PosAV; +}; + + +#define SALT_SIZE 8 + +struct FileHeader:BlockHeader +{ + uint UnpSize; + byte HostOS; + uint FileCRC; + uint FileTime; + byte UnpVer; + byte Method; + ushort NameSize; + union { + uint FileAttr; + uint SubFlags; + }; +/* optional */ + uint HighPackSize; + uint HighUnpSize; +/* names */ + char FileName[NM]; + wchar FileNameW[NM]; +/* optional */ + Array<byte> SubData; + byte Salt[SALT_SIZE]; + + RarTime mtime; + RarTime ctime; + RarTime atime; + RarTime arctime; +/* dummy */ + Int64 FullPackSize; + Int64 FullUnpSize; + + void Clear(int SubDataSize) + { + SubData.Alloc(SubDataSize); + Flags=LONG_BLOCK; + SubFlags=0; + } + + bool CmpName(const char *Name) + { + return(strcmp(FileName,Name)==0); + } + + FileHeader& operator = (FileHeader &hd) + { + SubData.Reset(); + memcpy(this,&hd,sizeof(*this)); + SubData.CleanData(); + SubData=hd.SubData; + return(*this); + } +}; + + +struct EndArcHeader:BaseBlock +{ + uint ArcDataCRC; + ushort VolNumber; +}; + + +struct SubBlockHeader:BlockHeader +{ + ushort SubType; + byte Level; +}; + + +struct CommentHeader:BaseBlock +{ + ushort UnpSize; + byte UnpVer; + byte Method; + ushort CommCRC; +}; + + +struct ProtectHeader:BlockHeader +{ + byte Version; + ushort RecSectors; + uint TotalBlocks; + byte Mark[8]; +}; + + +struct AVHeader:BaseBlock +{ + byte UnpVer; + byte Method; + byte AVVer; + uint AVInfoCRC; +}; + + +struct SignHeader:BaseBlock +{ + uint CreationTime; + ushort ArcNameSize; + ushort UserNameSize; +}; + + +struct UnixOwnersHeader:SubBlockHeader +{ + ushort OwnerNameSize; + ushort GroupNameSize; +/* dummy */ + char OwnerName[NM]; + char GroupName[NM]; +}; + + +struct EAHeader:SubBlockHeader +{ + uint UnpSize; + byte UnpVer; + byte Method; + uint EACRC; +}; + + +struct StreamHeader:SubBlockHeader +{ + uint UnpSize; + byte UnpVer; + byte Method; + uint StreamCRC; + ushort StreamNameSize; +/* dummy */ + byte StreamName[NM]; +}; + + +struct MacFInfoHeader:SubBlockHeader +{ + uint fileType; + uint fileCreator; +}; + + +#endif diff --git a/7zip/Compress/Rar29/Original/int64.cpp b/7zip/Compress/Rar29/Original/int64.cpp new file mode 100755 index 00000000..996d0ea6 --- /dev/null +++ b/7zip/Compress/Rar29/Original/int64.cpp @@ -0,0 +1,274 @@ +#include "rar.hpp" + +#ifndef NATIVE_INT64 + +Int64::Int64() +{ +} + + +Int64::Int64(uint n) +{ + HighPart=0; + LowPart=n; +} + + +Int64::Int64(uint HighPart,uint LowPart) +{ + Int64::HighPart=HighPart; + Int64::LowPart=LowPart; +} + + +/* +Int64 Int64::operator = (Int64 n) +{ + HighPart=n.HighPart; + LowPart=n.LowPart; + return(*this); +} +*/ + + +Int64 Int64::operator << (int n) +{ + Int64 res=*this; + while (n--) + { + res.HighPart<<=1; + if (res.LowPart & 0x80000000) + res.HighPart|=1; + res.LowPart<<=1; + } + return(res); +} + + +Int64 Int64::operator >> (int n) +{ + Int64 res=*this; + while (n--) + { + res.LowPart>>=1; + if (res.HighPart & 1) + res.LowPart|=0x80000000; + res.HighPart>>=1; + } + return(res); +} + + +Int64 operator / (Int64 n1,Int64 n2) +{ + if (n1.HighPart==0 && n2.HighPart==0) + return(Int64(0,n1.LowPart/n2.LowPart)); + int ShiftCount=0; + while (n1>n2) + { + n2=n2<<1; + if (++ShiftCount>64) + return(0); + } + Int64 res=0; + while (ShiftCount-- >= 0) + { + res=res<<1; + if (n1>=n2) + { + n1-=n2; + ++res; + } + n2=n2>>1; + } + return(res); +} + + +Int64 operator * (Int64 n1,Int64 n2) +{ + if (n1<0x10000 && n2<0x10000) + return(Int64(0,n1.LowPart*n2.LowPart)); + Int64 res=0; + for (int I=0;I<64;I++) + { + if (n2.LowPart & 1) + res+=n1; + n1=n1<<1; + n2=n2>>1; + } + return(res); +} + + +Int64 operator % (Int64 n1,Int64 n2) +{ + if (n1.HighPart==0 && n2.HighPart==0) + return(Int64(0,n1.LowPart%n2.LowPart)); + return(n1-n1/n2*n2); +} + + +Int64 operator + (Int64 n1,Int64 n2) +{ + n1.LowPart+=n2.LowPart; + if (n1.LowPart<n2.LowPart) + n1.HighPart++; + n1.HighPart+=n2.HighPart; + return(n1); +} + + +Int64 operator - (Int64 n1,Int64 n2) +{ + if (n1.LowPart<n2.LowPart) + n1.HighPart--; + n1.LowPart-=n2.LowPart; + n1.HighPart-=n2.HighPart; + return(n1); +} + + +Int64 operator += (Int64 &n1,Int64 n2) +{ + n1=n1+n2; + return(n1); +} + + +Int64 operator -= (Int64 &n1,Int64 n2) +{ + n1=n1-n2; + return(n1); +} + + +Int64 operator *= (Int64 &n1,Int64 n2) +{ + n1=n1*n2; + return(n1); +} + + +Int64 operator /= (Int64 &n1,Int64 n2) +{ + n1=n1/n2; + return(n1); +} + + +Int64 operator | (Int64 n1,Int64 n2) +{ + n1.LowPart|=n2.LowPart; + n1.HighPart|=n2.HighPart; + return(n1); +} + + +Int64 operator & (Int64 n1,Int64 n2) +{ + n1.LowPart&=n2.LowPart; + n1.HighPart&=n2.HighPart; + return(n1); +} + + +/* +inline void operator -= (Int64 &n1,unsigned int n2) +{ + if (n1.LowPart<n2) + n1.HighPart--; + n1.LowPart-=n2; +} + + +inline void operator ++ (Int64 &n) +{ + if (++n.LowPart == 0) + ++n.HighPart; +} + + +inline void operator -- (Int64 &n) +{ + if (n.LowPart-- == 0) + n.HighPart--; +} +*/ + +bool operator == (Int64 n1,Int64 n2) +{ + return(n1.LowPart==n2.LowPart && n1.HighPart==n2.HighPart); +} + + +bool operator > (Int64 n1,Int64 n2) +{ + return((int)n1.HighPart>(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart>n2.LowPart); +} + + +bool operator < (Int64 n1,Int64 n2) +{ + return((int)n1.HighPart<(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart<n2.LowPart); +} + + +bool operator != (Int64 n1,Int64 n2) +{ + return(n1.LowPart!=n2.LowPart || n1.HighPart!=n2.HighPart); +} + + +bool operator >= (Int64 n1,Int64 n2) +{ + return(n1>n2 || n1==n2); +} + + +bool operator <= (Int64 n1,Int64 n2) +{ + return(n1<n2 || n1==n2); +} + + +void Int64::Set(uint HighPart,uint LowPart) +{ + Int64::HighPart=HighPart; + Int64::LowPart=LowPart; +} +#endif + +void itoa(Int64 n,char *Str) +{ + if (n<=0xffffffff) + { + sprintf(Str,"%u",int64to32(n)); + return; + } + + char NumStr[50]; + int Pos=0; + + do + { + NumStr[Pos++]=int64to32(n%10)+'0'; + n=n/10; + } while (n!=0); + + for (int I=0;I<Pos;I++) + Str[I]=NumStr[Pos-I-1]; + Str[Pos]=0; +} + + +Int64 atoil(char *Str) +{ + Int64 n=0; + while (*Str>='0' && *Str<='9') + { + n=n*10+*Str-'0'; + Str++; + } + return(n); +} diff --git a/7zip/Compress/Rar29/Original/int64.hpp b/7zip/Compress/Rar29/Original/int64.hpp new file mode 100755 index 00000000..a8057522 --- /dev/null +++ b/7zip/Compress/Rar29/Original/int64.hpp @@ -0,0 +1,86 @@ +#ifndef _RAR_INT64_ +#define _RAR_INT64_ + +#if defined(__BORLANDC__) || defined(_MSC_VER) +#define NATIVE_INT64 +typedef __int64 Int64; +#endif + +#if defined(__GNUC__) || defined(__HP_aCC) +#define NATIVE_INT64 +typedef long long Int64; +#endif + +#ifdef NATIVE_INT64 + +#define int64to32(x) ((uint)(x)) +#define int32to64(high,low) ((((Int64)(high))<<32)+(low)) +#define is64plus(x) (x>=0) + +#else + +class Int64 +{ + public: + Int64(); + Int64(uint n); + Int64(uint HighPart,uint LowPart); + +// Int64 operator = (Int64 n); + Int64 operator << (int n); + Int64 operator >> (int n); + + friend Int64 operator / (Int64 n1,Int64 n2); + friend Int64 operator * (Int64 n1,Int64 n2); + friend Int64 operator % (Int64 n1,Int64 n2); + friend Int64 operator + (Int64 n1,Int64 n2); + friend Int64 operator - (Int64 n1,Int64 n2); + friend Int64 operator += (Int64 &n1,Int64 n2); + friend Int64 operator -= (Int64 &n1,Int64 n2); + friend Int64 operator *= (Int64 &n1,Int64 n2); + friend Int64 operator /= (Int64 &n1,Int64 n2); + friend Int64 operator | (Int64 n1,Int64 n2); + friend Int64 operator & (Int64 n1,Int64 n2); + inline friend void operator -= (Int64 &n1,unsigned int n2) + { + if (n1.LowPart<n2) + n1.HighPart--; + n1.LowPart-=n2; + } + inline friend void operator ++ (Int64 &n) + { + if (++n.LowPart == 0) + ++n.HighPart; + } + inline friend void operator -- (Int64 &n) + { + if (n.LowPart-- == 0) + n.HighPart--; + } + friend bool operator == (Int64 n1,Int64 n2); + friend bool operator > (Int64 n1,Int64 n2); + friend bool operator < (Int64 n1,Int64 n2); + friend bool operator != (Int64 n1,Int64 n2); + friend bool operator >= (Int64 n1,Int64 n2); + friend bool operator <= (Int64 n1,Int64 n2); + + void Set(uint HighPart,uint LowPart); + uint GetLowPart() {return(LowPart);} + + uint LowPart; + uint HighPart; +}; + +inline uint int64to32(Int64 n) {return(n.GetLowPart());} +#define int32to64(high,low) (Int64((high),(low))) +#define is64plus(x) ((int)(x).HighPart>=0) + +#endif + +#define INT64ERR int32to64(0x80000000,0) +#define INT64MAX int32to64(0x7fffffff,0) + +void itoa(Int64 n,char *Str); +Int64 atoil(char *Str); + +#endif diff --git a/7zip/Compress/Rar29/Original/isnt.hpp b/7zip/Compress/Rar29/Original/isnt.hpp new file mode 100755 index 00000000..02652361 --- /dev/null +++ b/7zip/Compress/Rar29/Original/isnt.hpp @@ -0,0 +1,6 @@ +#ifndef _RAR_ISNT_ +#define _RAR_ISNT_ + +int WinNT(); + +#endif diff --git a/7zip/Compress/Rar29/Original/list.hpp b/7zip/Compress/Rar29/Original/list.hpp new file mode 100755 index 00000000..7721ae52 --- /dev/null +++ b/7zip/Compress/Rar29/Original/list.hpp @@ -0,0 +1,6 @@ +#ifndef _RAR_LIST_ +#define _RAR_LIST_ + +void ListArchive(CommandData *Cmd); + +#endif diff --git a/7zip/Compress/Rar29/Original/loclang.hpp b/7zip/Compress/Rar29/Original/loclang.hpp new file mode 100755 index 00000000..05eefdde --- /dev/null +++ b/7zip/Compress/Rar29/Original/loclang.hpp @@ -0,0 +1,340 @@ +#define MYesNo "_Yes_No" +#define MYesNoAll "_Yes_No_All" +#define MYesNoAllRenQ "_Yes_No_All_nEver_Rename_Quit" +#define MContinueQuit "_Continue_Quit" +#define MRetryAbort "_Retry_Abort" +#define MCopyright "\nRAR %s Copyright (c) 1993-%d Alexander Roshal %d %s %d" +#define MRegTo "\nRegistered to %s\n" +#define MShare "\nShareware version Type RAR -? for help\n" +#define MUCopyright "\nUNRAR %s freeware Copyright (c) 1993-%d Alexander Roshal\n" +#define MBeta "beta" +#define MMonthJan "Jan" +#define MMonthFeb "Feb" +#define MMonthMar "Mar" +#define MMonthApr "Apr" +#define MMonthMay "May" +#define MMonthJun "Jun" +#define MMonthJul "Jul" +#define MMonthAug "Aug" +#define MMonthSep "Sep" +#define MMonthOct "Oct" +#define MMonthNov "Nov" +#define MMonthDec "Dec" +#define MRARTitle1 "\nUsage: rar <command> -<switch 1> -<switch N> <archive> <files...>" +#define MUNRARTitle1 "\nUsage: unrar <command> -<switch 1> -<switch N> <archive> <files...>" +#define MRARTitle2 "\n <@listfiles...> <path_to_extract\\>" +#define MCHelpCmd "\n\n<Commands>" +#define MCHelpCmdA "\n a Add files to archive" +#define MCHelpCmdC "\n c Add archive comment" +#define MCHelpCmdCF "\n cf Add files comment" +#define MCHelpCmdCW "\n cw Write archive comment to file" +#define MCHelpCmdD "\n d Delete files from archive" +#define MCHelpCmdE "\n e Extract files to current directory" +#define MCHelpCmdF "\n f Freshen files in archive" +#define MCHelpCmdI "\n i[par]=<str> Find string in archives" +#define MCHelpCmdK "\n k Lock archive" +#define MCHelpCmdL "\n l[t,b] List archive [technical, bare]" +#define MCHelpCmdM "\n m[f] Move to archive [files only]" +#define MCHelpCmdP "\n p Print file to stdout" +#define MCHelpCmdR "\n r Repair archive" +#define MCHelpCmdRC "\n rc Reconstruct missing volumes" +#define MCHelpCmdRN "\n rn Rename archived files" +#define MCHelpCmdRR "\n rr[N] Add data recovery record" +#define MCHelpCmdRV "\n rv[N] Create recovery volumes" +#define MCHelpCmdS "\n s[name|-] Convert archive to or from SFX" +#define MCHelpCmdT "\n t Test archive files" +#define MCHelpCmdU "\n u Update files in archive" +#define MCHelpCmdV "\n v[t,b] Verbosely list archive [technical,bare]" +#define MCHelpCmdX "\n x Extract files with full path" +#define MCHelpSw "\n\n<Switches>" +#define MCHelpSwm "\n - Stop switches scanning" +#define MCHelpSwAC "\n ac Clear Archive attribute after compression or extraction" +#define MCHelpSwAD "\n ad Append archive name to destination path" +#define MCHelpSwAG "\n ag[format] Generate archive name using the current date" +#define MCHelpSwAO "\n ao Add files with Archive attribute set" +#define MCHelpSwAP "\n ap<path> Set path inside archive" +#define MCHelpSwAS "\n as Synchronize archive contents" +#define MCHelpSwAV "\n av Put authenticity verification (registered versions only)" +#define MCHelpSwAVm "\n av- Disable authenticity verification check" +#define MCHelpSwCm "\n c- Disable comments show" +#define MCHelpSwCFGm "\n cfg- Disable read configuration" +#define MCHelpSwCL "\n cl Convert names to lower case" +#define MCHelpSwCU "\n cu Convert names to upper case" +#define MCHelpSwDF "\n df Delete files after archiving" +#define MCHelpSwDH "\n dh Open shared files" +#define MCHelpSwDS "\n ds Disable name sort for solid archive" +#define MCHelpSwEa "\n e[+]<attr> Set file exclude and include attributes" +#define MCHelpSwED "\n ed Do not add empty directories" +#define MCHelpSwEE "\n ee Do not save and extract extended attributes" +#define MCHelpSwEN "\n en Do not put 'end of archive' block" +#define MCHelpSwEP "\n ep Exclude paths from names" +#define MCHelpSwEP1 "\n ep1 Exclude base directory from names" +#define MCHelpSwEP2 "\n ep2 Expand paths to full" +#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter" +#define MCHelpSwF "\n f Freshen files" +#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers" +#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages" +#define MCHelpSwIEML "\n ieml[addr] Send archive by email" +#define MCHelpSwIERR "\n ierr Send all messages to stderr" +#define MCHelpSwILOG "\n ilog[name] Log errors to file (registered versions only)" +#define MCHelpSwINUL "\n inul Disable all messages" +#define MCHelpSwIOFF "\n ioff Turn PC off after completing an operation" +#define MCHelpSwISND "\n isnd Enable sound" +#define MCHelpSwK "\n k Lock archive" +#define MCHelpSwKB "\n kb Keep broken extracted files" +#define MCHelpSwMn "\n m<0..5> Set compression level (0-store...3-default...5-maximal)" +#define MCHelpSwMC "\n mc<par> Set advanced compression parameters" +#define MCHelpSwMD "\n md<size> Dictionary size in KB (64,128,256,512,1024,2048,4096 or A-G)" +#define MCHelpSwMS "\n ms[ext;ext] Specify file types to store" +#define MCHelpSwN "\n n<file> Include only specified file" +#define MCHelpSwNa "\n n@ Read file names to include from stdin" +#define MCHelpSwNal "\n n@<list> Include files in specified list file" +#define MCHelpSwOp "\n o+ Overwrite existing files" +#define MCHelpSwOm "\n o- Do not overwrite existing files" +#define MCHelpSwOC "\n oc Set NTFS Compressed attribute" +#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file" +#define MCHelpSwOS "\n os Save NTFS streams" +#define MCHelpSwOW "\n ow Save or restore file owner and group" +#define MCHelpSwP "\n p[password] Set password" +#define MCHelpSwPm "\n p- Do not query password" +#define MCHelpSwR "\n r Recurse subdirectories" +#define MCHelpSwR0 "\n r0 Recurse subdirectories for wildcard names only" +#define MCHelpSwRI "\n ri<P>[:<S>] Set priority (0-default,1-min..15-max) and sleep time in ms" +#define MCHelpSwRR "\n rr[N] Add data recovery record" +#define MCHelpSwRV "\n rv[N] Create recovery volumes" +#define MCHelpSwS "\n s[<N>,v[-],e] Create solid archive" +#define MCHelpSwSm "\n s- Disable solid archiving" +#define MCHelpSwSFX "\n sfx[name] Create SFX archive" +#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)" +#define MCHelpSwT "\n t Test files after archiving" +#define MCHelpSwTK "\n tk Keep original archive time" +#define MCHelpSwTL "\n tl Set archive time to latest file" +#define MCHelpSwTN "\n tn<time> Process files newer than <time>" +#define MCHelpSwTO "\n to<time> Process files older than <time>" +#define MCHelpSwTA "\n ta<date> Process files modified after <date> in YYYYMMDDHHMMSS format" +#define MCHelpSwTB "\n tb<date> Process files modified before <date> in YYYYMMDDHHMMSS format" +#define MCHelpSwTS "\n ts<m,c,a>[N] Save or restore file time (modification, creation, access)" +#define MCHelpSwU "\n u Update files" +#define MCHelpSwV "\n v Create volumes with size autodetection or list all volumes" +#define MCHelpSwVUnr "\n v List all volumes" +#define MCHelpSwVn "\n v<size>[k,b] Create volumes with size=<size>*1000 [*1024, *1]" +#define MCHelpSwVD "\n vd Erase disk contents before creating volume" +#define MCHelpSwVER "\n ver[n] File version control" +#define MCHelpSwVN "\n vn Use the old style volume naming scheme" +#define MCHelpSwVP "\n vp Pause before each volume" +#define MCHelpSwW "\n w<path> Assign work directory" +#define MCHelpSwX "\n x<file> Exclude specified file" +#define MCHelpSwXa "\n x@ Read file names to exclude from stdin" +#define MCHelpSwXal "\n x@<list> Exclude files in specified list file" +#define MCHelpSwY "\n y Assume Yes on all queries" +#define MCHelpSwZ "\n z<file> Read archive comment from file" +#define MBadArc "\nERROR: Bad archive %s\n" +#define MAskPsw "Enter password (will not be echoed)" +#define MAskPswEcho "Enter password" +#define MReAskPsw "\nReenter password: " +#define MFor " for " +#define MNotMatchPsw "\nERROR: Passwords do not match\n" +#define MErrWrite "Write error in the file %s" +#define MErrRead "Read error in the file %s" +#define MErrSeek "Seek error in the file %s" +#define MErrFClose "Cannot close the file %s" +#define MErrOutMem "Not enough memory" +#define MErrBrokenArc "Corrupt archive - use 'Repair' command" +#define MProgAborted "Program aborted" +#define MErrRename "\nCannot rename %s to %s" +#define MAbsNextVol "\nCannot find volume %s" +#define MBreak "\nUser break\n" +#define MAskCreatVol "\nCreate next volume ?" +#define MAskNextDisk "\nDisk full. Insert next" +#define MCreatVol "\n\nCreating %sarchive %s\n" +#define MAskNextVol "\nInsert disk with %s" +#define MTestVol "\n\nTesting archive %s\n" +#define MExtrVol "\n\nExtracting from %s\n" +#define MConverting "\nConverting %s" +#define MCvtToSFX "\nConvert archives to SFX" +#define MCvtFromSFX "\nRemoving SFX module" +#define MNotSFX "\n%s is not SFX archive" +#define MNotRAR "\n%s is not RAR archive" +#define MNotFirstVol "\n%s is not the first volume" +#define MCvtOldFormat "\n%s - cannot convert to SFX archive with old format" +#define MCannotCreate "\nCannot create %s" +#define MCannotOpen "\nCannot open %s" +#define MUnknownMeth "\nUnknown method in %s" +#define MVerRequired "\nYou need RAR %d.%d to unpack it" +#define MOk " OK" +#define MDone "\nDone" +#define MLockingArc "\nLocking archive" +#define MNotMdfOld "\n\nERROR: Cannot modify old format archive" +#define MNotMdfLock "\n\nERROR: Locked archive" +#define MNotMdfVol "\n\nERROR: Cannot modify volume" +#define MVerifyAV "\nVerifying authenticity information ... " +#define MFailedAV " Failed\n" +#define MStrAV1 "\n\nArchive %s" +#define MStrAV2 "\ncreated at %s" +#define MStrAV3 "\nby %s\n" +#define MLogFailedAV "Invalid authenticity information" +#define MAddingAV "\nAdding authenticity verification " +#define MAVOldStyle "\n\nOld style authenticity information" +#define MPackAskReg "\nEvaluation copy. Please register.\n" +#define MCreateArchive "\nCreating %sarchive %s\n" +#define MUpdateArchive "\nUpdating %sarchive %s\n" +#define MAddSolid "solid " +#define MAddFile "\nAdding %-58s " +#define MUpdFile "\nUpdating %-58s " +#define MAddPoints "\n... %-58s " +#define MCannotUpdPswSolid "\nERROR: Cannot update solid archives with password\n" +#define MMoveDelFiles "\n\nDeleting files %s..." +#define MMoveDelDirs "and directories" +#define MMoveDelFile "\nDeleting %-30s" +#define MMoveDeleted " deleted" +#define MMoveNotDeleted " NOT DELETED" +#define MClearAttrib "\n\nClearing attributes..." +#define MMoveDelDir "\nDeleting directory %-30s" +#define MWarErrFOpen "\nWARNING: Cannot open %d %s" +#define MErrOpenFiles "files" +#define MErrOpenFile "file" +#define MAddNoFiles "\nWARNING: No files" +#define MMdfEncrSol "\n%s: encrypted" +#define MCannotMdfEncrSol "\nCannot modify solid archive containing encrypted files" +#define MAddAnalyze "\nAnalyzing archived files: " +#define MRepacking "\nRepacking archived files: " +#define MCRCFailed "\n%-20s - CRC failed" +#define MExtrTest "\n\nTesting archive %s\n" +#define MExtracting "\n\nExtracting from %s\n" +#define MUseCurPsw "\n%s - use current password ?" +#define MCreatDir "\nCreating %-56s" +#define MExtrSkipFile "\nSkipping %-56s" +#define MExtrTestFile "\nTesting %-56s" +#define MExtrFile "\nExtracting %-56s" +#define MExtrPoints "\n... %-56s" +#define MExtrErrMkDir "\nCannot create directory %s" +#define MExtrPrinting "\n------ Printing %s\n\n" +#define MEncrBadCRC "\nEncrypted file: CRC failed in %s (password incorrect ?)" +#define MExtrNoFiles "\nNo files to extract" +#define MExtrAllOk "\nAll OK" +#define MExtrTotalErr "\nTotal errors: %ld" +#define MFileExists "\n\n%s already exists. Overwrite it ?" +#define MAskOverwrite "\nOverwrite %s ?" +#define MAskNewName "\nEnter new name: " +#define MLogMainHead "\nThe archive header is corrupt" +#define MLogFileHead "\n%s - the file header is corrupt" +#define MLogCommHead "\nThe comment header is corrupt\n" +#define MLogProtectHead "The data recovery header is corrupt" +#define MReadStdinCmt "\nReading comment from stdin\n" +#define MReadCommFrom "\nReading comment from %s" +#define MDelComment "\nDeleting comment from %s" +#define MAddComment "\nAdding comment to %s" +#define MFCommAdd "\nAdding file comments" +#define MAskFComm "\n\nReading comment for %s : %s from stdin\n" +#define MLogCommBrk "\nThe archive comment is corrupt" +#define MCommAskCont "\nPress 'Enter' to continue or 'Q' to quit:" +#define MLogBrokFCmt "\nThe file comment is corrupt" +#define MAbsDestName "\nDestination file name required" +#define MWriteCommTo "\nWrite comment to %s" +#define MCommNotPres "\nComment is not present" +#define MDelFrom "\nDeleting from %s" +#define MDeleting "\nDeleting %s" +#define MEraseArc "\nErasing empty archive %s" +#define MNoDelFiles "\nNo files to delete" +#define MLogTitle "\n\n-------- %2d %s %d, archive %s\n" +#define MPathTooLong "\nERROR: Path too long\n" +#define MListSolid "Solid " +#define MListSFX "SFX " +#define MListVol1 "volume" +#define MListVol2 "Volume" +#define MListArc1 "archive" +#define MListArc2 "Archive" +#define MListRecRec "\nRecovery record is present\n" +#define MListLock "\nLock is present\n" +#define MListPathComm "\nPathname/Comment\n " +#define MListName "\n Name " +#define MListTitle " Size Packed Ratio Date Time Attr CRC Meth Ver\n" +#define MListTechTitle " Host OS Solid Old\n" +#define MListEAHead "\n OS/2 extended attributes" +#define MListUOHead "\n Unix Owner/Group data: %-14s %-14s" +#define MListBeEAHead "\n BeOS extended attributes" +#define MListNTACLHead "\n NTFS security data" +#define MListStrmHead "\n NTFS stream: %s" +#define MListUnkHead "\n Unknown subheader type: 0x%04x" +#define MFileComment "\nComment: " +#define MYes "Yes" +#define MNo "No" +#define MListNoFiles " 0 files\n" +#define MRprReconstr "\nReconstructing %s" +#define MRprBuild "\nBuilding %s" +#define MRprOldFormat "\nCannot repair archive with old format" +#define MRprFind "\nFound %s" +#define MRprAskIsSol "\nThe archive header is corrupt. Mark archive as solid ?" +#define MRprNoFiles "\nNo files found" +#define MRprSuspEntry "\n\nSuspicious entry %s" +#define MRprDir "\nDirectory" +#define MRprSuspSize "\nSize %ld Packed %ld" +#define MRprSuspAdd "\nAdd it to archive ?" +#define MLogUnexpEOF "\nUnexpected end of archive" +#define MRepAskReconst "\nReconstruct archive structure ?" +#define MRecScanning "\nScanning..." +#define MRecRNotFound "\nData recovery record not found" +#define MRecRFound "\nData recovery record found" +#define MRecSecDamage "\nSector %ld (offsets %lX...%lX) damaged" +#define MRecCorrected " - data recovered" +#define MRecFailed " - cannot recover data" +#define MAddRecRec "\nAdding data recovery record" +#define MEraseForVolume "\n\nErasing contents of drive %c:\n" +#define MGetOwnersError "\nWARNING: Cannot get %s owner and group\n" +#define MErrGetOwnerID "\nWARNING: Cannot get owner %s ID\n" +#define MErrGetGroupID "\nWARNING: Cannot get group %s ID\n" +#define MOwnersBroken "\nERROR: %s group and owner data are corrupt\n" +#define MSetOwnersError "\nWARNING: Cannot set %s owner and group\n" +#define MErrLnkRead "\nWARNING: Cannot read symbolic link %s" +#define MErrCreateLnk "\nWARNING: Cannot create link %s" +#define MSymLinkExists "\nWARNING: Symbolic link %s already exists" +#define MAskRetryCreate "\nCannot create %s. Retry ?" +#define MListMACHead1 "\n MacOS file type: %c%c%c%c ; " +#define MListMACHead2 "file creator: %c%c%c%c\n" +#define MDataBadCRC "\n%-20s : packed data CRC failed in volume %s" +#define MFileRO "\n%s is read-only" +#define MACLGetError "\nWARNING: Cannot get %s security data\n" +#define MACLSetError "\nWARNING: Cannot set %s security data\n" +#define MACLBroken "\nERROR: %s security data are corrupt\n" +#define MACLUnknown "\nWARNING: Unknown format of %s security data\n" +#define MStreamBroken "\nERROR: %s stream data are corrupt\n" +#define MStreamUnknown "\nWARNING: Unknown format of %s stream data\n" +#define MInvalidName "\nERROR: Invalid file name %s" +#define MEABroken "\nERROR: %s extended attributes are corrupt\n" +#define MEAUnknHeader "\nWARNING: %s - unknown format of extended attributes\n" +#define MCannotSetEA "\nWARNING: cannot set extended attributes to %s\n" +#define MCannotGetEA "\nERROR: Cannot get extended attributes of %s\n" +#define MShowEA " (+EA)" +#define MSkipEA "\n...skipping extended attributes" +#define MProcessArc "\n\nProcessing archive %s" +#define MSyncScanError "\nFile search errors, cannot synchronize archive" +#define MCorrectingName "\nWARNING: Attempting to correct the invalid file name" +#define MUnpCannotMerge "\nWARNING: You need to start extraction from a previous volume to unpack %s" +#define MUnknownOption "\nERROR: Unknown option: %s" +#define MSubHeadCorrupt "\nERROR: Corrupt data header found, ignored" +#define MSubHeadUnknown "\nWARNING: Unknown data header format, ignored" +#define MSubHeadDataCRC "\nERROR: Corrupt %s data block" +#define MSubHeadType "\nData header type: %s" +#define MScanError "\nCannot read contents of %s" +#define MNotVolume "\n%s is not volume" +#define MRecVolDiffSets "\nERROR: %s and %s belong to different sets" +#define MRecVolMissing "\n%d volumes missing" +#define MRecVolFound "\n%d recovery volumes found" +#define MRecVolAllExist "\nNothing to reconstruct" +#define MRecVolCannotFix "\nReconstruction impossible" +#define MReconstructing "\nReconstructing..." +#define MCreating "\nCreating %s" +#define MRenaming "\nRenaming %s to %s" +#define MNTFSRequired "\nWrite error: only NTFS file system supports files larger than 4 GB" +#define MErrChangeAttr "\nWARNING: Cannot change attributes of %s" +#define MWrongSFXVer "\nERROR: default SFX module does not support RAR %d.%d archives" +#define MCannotEncName "\nCannot encrypt archive already contained encrypted files" +#define MCannotEmail "\nCannot email the file %s" +#define MCopyrightS "\nRAR SFX archive" +#define MSHelpCmd "\n\n<Commands>" +#define MSHelpCmdE "\n -x Extract from archive (default)" +#define MSHelpCmdT "\n -t Test archive files" +#define MSHelpCmdV "\n -v Verbosely list contents of archive" +#define MMaxPathLimit "\nTotal path and file name length must not exceed %d characters" +#define MRecVolLimit "\nTotal number of usual and recovery volumes must not exceed 255" +#define MVolumeNumber "volume %d" diff --git a/7zip/Compress/Rar29/Original/log.hpp b/7zip/Compress/Rar29/Original/log.hpp new file mode 100755 index 00000000..52d6b8d5 --- /dev/null +++ b/7zip/Compress/Rar29/Original/log.hpp @@ -0,0 +1,18 @@ +#ifndef _RAR_LOG_ +#define _RAR_LOG_ + +void InitLogOptions(char *LogName); + +#ifndef SILENT +void Log(const char *ArcName,const char *Format,...); +#endif + +#ifdef SILENT +#ifdef __GNUC__ +#define Log(args...) +#else +inline void Log(const char *a,const char *b,const char *c=NULL,const char *d=NULL) {} +#endif +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/match.hpp b/7zip/Compress/Rar29/Original/match.hpp new file mode 100755 index 00000000..a7367772 --- /dev/null +++ b/7zip/Compress/Rar29/Original/match.hpp @@ -0,0 +1,16 @@ +#ifndef _RAR_MATCH_ +#define _RAR_MATCH_ + +enum {MATCH_NAMES,MATCH_PATH,MATCH_EXACTPATH,MATCH_SUBPATH,MATCH_WILDSUBPATH}; + +#define MATCH_MODEMASK 0x0000ffff + +bool CmpName(char *Wildcard,char *Name,int CmpPath); +bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath); + +int stricompc(const char *Str1,const char *Str2); +int stricompcw(const wchar *Str1,const wchar *Str2); +int strnicompc(const char *Str1,const char *Str2,int N); +int strnicompcw(const wchar *Str1,const wchar *Str2,int N); + +#endif diff --git a/7zip/Compress/Rar29/Original/model.cpp b/7zip/Compress/Rar29/Original/model.cpp new file mode 100755 index 00000000..e708feb2 --- /dev/null +++ b/7zip/Compress/Rar29/Original/model.cpp @@ -0,0 +1,600 @@ +/**************************************************************************** + * This file is part of PPMd project * + * Written and distributed to public domain by Dmitry Shkarin 1997, * + * 1999-2000 * + * Contents: model description and encoding/decoding routines * + ****************************************************************************/ + +inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats, + STATE& FirstState) +{ + PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext(); + if ( pc ) + { + pc->NumStats=1; + pc->OneState=FirstState; + pc->Suffix=this; + pStats->Successor=pc; + } + return pc; +} + + +ModelPPM::ModelPPM() +{ + MinContext=NULL; + MaxContext=NULL; + MedContext=NULL; +} + + +void ModelPPM::RestartModelRare() +{ + int i, k, m; + memset(CharMask,0,sizeof(CharMask)); + SubAlloc.InitSubAllocator(); + InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1; + MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext(); + MinContext->Suffix=NULL; + OrderFall=MaxOrder; + MinContext->U.SummFreq=(MinContext->NumStats=256)+1; + FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2); + for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++) + { + MinContext->U.Stats[i].Symbol=i; + MinContext->U.Stats[i].Freq=1; + MinContext->U.Stats[i].Successor=NULL; + } + + static const ushort InitBinEsc[]={ + 0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051 + }; + + for (i=0;i < 128;i++) + for (k=0;k < 8;k++) + for (m=0;m < 64;m += 8) + BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2); + for (i=0;i < 25;i++) + for (k=0;k < 16;k++) + SEE2Cont[i][k].init(5*i+10); +} + + +void ModelPPM::StartModelRare(int MaxOrder) +{ + int i, k, m ,Step; + EscCount=1; +/* + if (MaxOrder < 2) + { + memset(CharMask,0,sizeof(CharMask)); + OrderFall=ModelPPM::MaxOrder; + MinContext=MaxContext; + while (MinContext->Suffix != NULL) + { + MinContext=MinContext->Suffix; + OrderFall--; + } + FoundState=MinContext->U.Stats; + MinContext=MaxContext; + } + else +*/ + { + ModelPPM::MaxOrder=MaxOrder; + RestartModelRare(); + NS2BSIndx[0]=2*0; + NS2BSIndx[1]=2*1; + memset(NS2BSIndx+2,2*2,9); + memset(NS2BSIndx+11,2*3,256-11); + for (i=0;i < 3;i++) + NS2Indx[i]=i; + for (m=i, k=Step=1;i < 256;i++) + { + NS2Indx[i]=m; + if ( !--k ) + { + k = ++Step; + m++; + } + } + memset(HB2Flag,0,0x40); + memset(HB2Flag+0x40,0x08,0x100-0x40); + DummySEE2Cont.Shift=PERIOD_BITS; + } +} + + +void PPM_CONTEXT::rescale(ModelPPM *Model) +{ + int OldNS=NumStats, i=NumStats-1, Adder, EscFreq; + STATE* p1, * p; + for (p=Model->FoundState;p != U.Stats;p--) + _PPMD_SWAP(p[0],p[-1]); + U.Stats->Freq += 4; + U.SummFreq += 4; + EscFreq=U.SummFreq-p->Freq; + Adder=(Model->OrderFall != 0); + U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1); + do + { + EscFreq -= (++p)->Freq; + U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1); + if (p[0].Freq > p[-1].Freq) + { + STATE tmp=*(p1=p); + do + { + p1[0]=p1[-1]; + } while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq); + *p1=tmp; + } + } while ( --i ); + if (p->Freq == 0) + { + do + { + i++; + } while ((--p)->Freq == 0); + EscFreq += i; + if ((NumStats -= i) == 1) + { + STATE tmp=*U.Stats; + do + { + tmp.Freq-=(tmp.Freq >> 1); + EscFreq>>=1; + } while (EscFreq > 1); + Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1); + *(Model->FoundState=&OneState)=tmp; return; + } + } + U.SummFreq += (EscFreq -= (EscFreq >> 1)); + int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1; + if (n0 != n1) + U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1); + Model->FoundState=U.Stats; +} + + +inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1) +{ +#ifdef __ICL + static +#endif + STATE UpState; + PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor; + STATE * p, * ps[MAX_O], ** pps=ps; + if ( !Skip ) + { + *pps++ = FoundState; + if ( !pc->Suffix ) + goto NO_LOOP; + } + if ( p1 ) + { + p=p1; + pc=pc->Suffix; + goto LOOP_ENTRY; + } + do + { + pc=pc->Suffix; + if (pc->NumStats != 1) + { + if ((p=pc->U.Stats)->Symbol != FoundState->Symbol) + do + { + p++; + } while (p->Symbol != FoundState->Symbol); + } + else + p=&(pc->OneState); +LOOP_ENTRY: + if (p->Successor != UpBranch) + { + pc=p->Successor; + break; + } + *pps++ = p; + } while ( pc->Suffix ); +NO_LOOP: + if (pps == ps) + return pc; + UpState.Symbol=*(byte*) UpBranch; + UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1); + if (pc->NumStats != 1) + { + if ((byte*) pc <= SubAlloc.pText) + return(NULL); + if ((p=pc->U.Stats)->Symbol != UpState.Symbol) + do + { + p++; + } while (p->Symbol != UpState.Symbol); + uint cf=p->Freq-1; + uint s0=pc->U.SummFreq-pc->NumStats-cf; + UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0))); + } + else + UpState.Freq=pc->OneState.Freq; + do + { + pc = pc->createChild(this,*--pps,UpState); + if ( !pc ) + return NULL; + } while (pps != ps); + return pc; +} + + +inline void ModelPPM::UpdateModel() +{ + STATE fs = *FoundState, *p = NULL; + PPM_CONTEXT *pc, *Successor; + uint ns1, ns, cf, sf, s0; + if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL) + { + if (pc->NumStats != 1) + { + if ((p=pc->U.Stats)->Symbol != fs.Symbol) + { + do + { + p++; + } while (p->Symbol != fs.Symbol); + if (p[0].Freq >= p[-1].Freq) + { + _PPMD_SWAP(p[0],p[-1]); + p--; + } + } + if (p->Freq < MAX_FREQ-9) + { + p->Freq += 2; + pc->U.SummFreq += 2; + } + } + else + { + p=&(pc->OneState); + p->Freq += (p->Freq < 32); + } + } + if ( !OrderFall ) + { + MinContext=MaxContext=FoundState->Successor=CreateSuccessors(TRUE,p); + if ( !MinContext ) + goto RESTART_MODEL; + return; + } + *SubAlloc.pText++ = fs.Symbol; + Successor = (PPM_CONTEXT*) SubAlloc.pText; + if (SubAlloc.pText >= SubAlloc.FakeUnitsStart) + goto RESTART_MODEL; + if ( fs.Successor ) + { + if ((byte*) fs.Successor <= SubAlloc.pText && + (fs.Successor=CreateSuccessors(FALSE,p)) == NULL) + goto RESTART_MODEL; + if ( !--OrderFall ) + { + Successor=fs.Successor; + SubAlloc.pText -= (MaxContext != MinContext); + } + } + else + { + FoundState->Successor=Successor; + fs.Successor=MinContext; + } + s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1); + for (pc=MaxContext;pc != MinContext;pc=pc->Suffix) + { + if ((ns1=pc->NumStats) != 1) + { + if ((ns1 & 1) == 0) + { + pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1); + if ( !pc->U.Stats ) + goto RESTART_MODEL; + } + pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1)); + } + else + { + p=(STATE*) SubAlloc.AllocUnits(1); + if ( !p ) + goto RESTART_MODEL; + *p=pc->OneState; + pc->U.Stats=p; + if (p->Freq < MAX_FREQ/4-1) + p->Freq += p->Freq; + else + p->Freq = MAX_FREQ-4; + pc->U.SummFreq=p->Freq+InitEsc+(ns > 3); + } + cf=2*fs.Freq*(pc->U.SummFreq+6); + sf=s0+pc->U.SummFreq; + if (cf < 6*sf) + { + cf=1+(cf > sf)+(cf >= 4*sf); + pc->U.SummFreq += 3; + } + else + { + cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf); + pc->U.SummFreq += cf; + } + p=pc->U.Stats+ns1; + p->Successor=Successor; + p->Symbol = fs.Symbol; + p->Freq = cf; + pc->NumStats=++ns1; + } + MaxContext=MinContext=fs.Successor; + return; +RESTART_MODEL: + RestartModelRare(); + EscCount=0; +} + + +// Tabulated escapes for exponential symbol distribution +static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; +#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT)) + + + +inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model) +{ + STATE& rs=OneState; + Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol]; + ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+ + Model->NS2BSIndx[Suffix->NumStats-1]+ + Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+ + ((Model->RunLength >> 26) & 0x20)]; + if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs) + { + Model->FoundState=&rs; + rs.Freq += (rs.Freq < 128); + Model->Coder.SubRange.LowCount=0; + Model->Coder.SubRange.HighCount=bs; + bs = SHORT16(bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2)); + Model->PrevSuccess=1; + Model->RunLength++; + } + else + { + Model->Coder.SubRange.LowCount=bs; + bs = SHORT16(bs-GET_MEAN(bs,PERIOD_BITS,2)); + Model->Coder.SubRange.HighCount=BIN_SCALE; + Model->InitEsc=ExpEscape[bs >> 10]; + Model->NumMasked=1; + Model->CharMask[rs.Symbol]=Model->EscCount; + Model->PrevSuccess=0; + Model->FoundState=NULL; + } +} + + +inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p) +{ + (Model->FoundState=p)->Freq += 4; + U.SummFreq += 4; + if (p[0].Freq > p[-1].Freq) + { + _PPMD_SWAP(p[0],p[-1]); + Model->FoundState=--p; + if (p->Freq > MAX_FREQ) + rescale(Model); + } +} + + + + +inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model) +{ + Model->Coder.SubRange.scale=U.SummFreq; + STATE* p=U.Stats; + int i, HiCnt; + int count=Model->Coder.GetCurrentCount(); + if (count>=Model->Coder.SubRange.scale) + return(false); + if (count < (HiCnt=p->Freq)) + { + Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale); + Model->RunLength += Model->PrevSuccess; + (Model->FoundState=p)->Freq=(HiCnt += 4); + U.SummFreq += 4; + if (HiCnt > MAX_FREQ) + rescale(Model); + Model->Coder.SubRange.LowCount=0; + return(true); + } + else + if (Model->FoundState==NULL) + return(false); + Model->PrevSuccess=0; + i=NumStats-1; + while ((HiCnt += (++p)->Freq) <= count) + if (--i == 0) + { + Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol]; + Model->Coder.SubRange.LowCount=HiCnt; + Model->CharMask[p->Symbol]=Model->EscCount; + i=(Model->NumMasked=NumStats)-1; + Model->FoundState=NULL; + do + { + Model->CharMask[(--p)->Symbol]=Model->EscCount; + } while ( --i ); + Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale; + return(true); + } + Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq; + update1(Model,p); + return(true); +} + + +inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p) +{ + (Model->FoundState=p)->Freq += 4; + U.SummFreq += 4; + if (p->Freq > MAX_FREQ) + rescale(Model); + Model->EscCount++; + Model->RunLength=Model->InitRL; +} + + +inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff) +{ + SEE2_CONTEXT* psee2c; + if (NumStats != 256) + { + psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+ + (Diff < Suffix->NumStats-NumStats)+ + 2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+ + Model->HiBitsFlag; + Model->Coder.SubRange.scale=psee2c->getMean(); + } + else + { + psee2c=&Model->DummySEE2Cont; + Model->Coder.SubRange.scale=1; + } + return psee2c; +} + + + + +inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model) +{ + int count, HiCnt, i=NumStats-Model->NumMasked; + SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i); + STATE* ps[256], ** pps=ps, * p=U.Stats-1; + HiCnt=0; + do + { + do + { + p++; + } while (Model->CharMask[p->Symbol] == Model->EscCount); + HiCnt += p->Freq; + *pps++ = p; + } while ( --i ); + Model->Coder.SubRange.scale += HiCnt; + count=Model->Coder.GetCurrentCount(); + if (count>=Model->Coder.SubRange.scale) + return(false); + p=*(pps=ps); + if (count < HiCnt) + { + HiCnt=0; + while ((HiCnt += p->Freq) <= count) + p=*++pps; + Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq; + psee2c->update(); + update2(Model,p); + } + else + { + Model->Coder.SubRange.LowCount=HiCnt; + Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale; + i=NumStats-Model->NumMasked; + pps--; + do + { + Model->CharMask[(*++pps)->Symbol]=Model->EscCount; + } while ( --i ); + psee2c->Summ += Model->Coder.SubRange.scale; + Model->NumMasked = NumStats; + } + return(true); +} + + +inline void ModelPPM::ClearMask() +{ + EscCount=1; + memset(CharMask,0,sizeof(CharMask)); +} + + + + +bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar) +{ + int MaxOrder=UnpackRead->GetChar(); + + // Igor Pavlov + bool Reset = ((MaxOrder & 0x20) != 0); + + int MaxMB; + if (Reset) + MaxMB=UnpackRead->GetChar(); + else + if (SubAlloc.GetAllocatedMemory()==0) + return(false); + if (MaxOrder & 0x40) + EscChar=UnpackRead->GetChar(); + Coder.InitDecoder(UnpackRead); + if (Reset) + { + MaxOrder=(MaxOrder & 0x1f)+1; + if (MaxOrder>16) + MaxOrder=16+(MaxOrder-16)*3; + if (MaxOrder==1) + { + SubAlloc.StopSubAllocator(); + return(false); + } + SubAlloc.StartSubAllocator(MaxMB+1); + StartModelRare(MaxOrder); + } + return(MinContext!=NULL); +} + + +int ModelPPM::DecodeChar() +{ + if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd) + return(-1); + if (MinContext->NumStats != 1) + { + if (!MinContext->decodeSymbol1(this)) + return(-1); + } + else + MinContext->decodeBinSymbol(this); + Coder.Decode(); + while ( !FoundState ) + { + ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead); + do + { + OrderFall++; + MinContext=MinContext->Suffix; + if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd) + return(-1); + } while (MinContext->NumStats == NumMasked); + if (!MinContext->decodeSymbol2(this)) + return(-1); + Coder.Decode(); + } + int Symbol=FoundState->Symbol; + if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText) + MinContext=MaxContext=FoundState->Successor; + else + { + UpdateModel(); + if (EscCount == 0) + ClearMask(); + } + ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead); + return(Symbol); +} diff --git a/7zip/Compress/Rar29/Original/model.hpp b/7zip/Compress/Rar29/Original/model.hpp new file mode 100755 index 00000000..1c3742b9 --- /dev/null +++ b/7zip/Compress/Rar29/Original/model.hpp @@ -0,0 +1,126 @@ +#ifndef _RAR_PPMMODEL_ +#define _RAR_PPMMODEL_ + +#include "coder.hpp" +#include "suballoc.hpp" + +const int MAX_O=64; /* maximum allowed model order */ + +const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, + INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; + +#pragma pack(1) + +struct SEE2_CONTEXT +{ // SEE-contexts for PPM-contexts with masked symbols + ushort Summ; + byte Shift, Count; + void init(int InitVal) + { + Summ=InitVal << (Shift=PERIOD_BITS-4); + Count=4; + } + uint getMean() + { + uint RetVal=SHORT16(Summ) >> Shift; + Summ -= RetVal; + return RetVal+(RetVal == 0); + } + void update() + { + if (Shift < PERIOD_BITS && --Count == 0) + { + Summ += Summ; + Count=3 << Shift++; + } + } +}; + + +class ModelPPM; +struct PPM_CONTEXT; + +struct STATE +{ + byte Symbol; + byte Freq; + PPM_CONTEXT* Successor; +}; + +struct FreqData +{ + ushort SummFreq; + STATE _PACK_ATTR * Stats; +}; + +struct PPM_CONTEXT +{ + ushort NumStats; + union + { + FreqData U; + STATE OneState; + }; + + PPM_CONTEXT* Suffix; + inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder: + inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context + inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix + inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor + inline bool decodeSymbol1(ModelPPM *Model); // other orders: + inline bool decodeSymbol2(ModelPPM *Model); // BCD context + inline void update1(ModelPPM *Model,STATE* p); // CD suffix + inline void update2(ModelPPM *Model,STATE* p); // BCDE successor + void rescale(ModelPPM *Model); + inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState); + inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff); +}; +#ifdef _AIX +#pragma pack(pop) +#else +#pragma pack() +#endif + +const uint UNIT_SIZE=sizeof(PPM_CONTEXT); +const uint FIXED_UNIT_SIZE=12; + +/* +inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext): + NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; } +inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {} +*/ + +template <class T> +inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; } + + +class ModelPPM +{ + private: + friend struct PPM_CONTEXT; + + _PACK_ATTR SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; + + struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext; + STATE* FoundState; // found next state transition + int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL; + byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; + byte EscCount, PrevSuccess, HiBitsFlag; + ushort BinSumm[128][64]; // binary SEE-contexts + + RangeCoder Coder; + SubAllocator SubAlloc; + + void RestartModelRare(); + void StartModelRare(int MaxOrder); + inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1); + + inline void UpdateModel(); + inline void ClearMask(); + public: + ModelPPM(); + bool DecodeInit(Unpack *UnpackRead,int &EscChar); + int DecodeChar(); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/options.hpp b/7zip/Compress/Rar29/Original/options.hpp new file mode 100755 index 00000000..b43739f6 --- /dev/null +++ b/7zip/Compress/Rar29/Original/options.hpp @@ -0,0 +1,129 @@ +#ifndef _RAR_OPTIONS_ +#define _RAR_OPTIONS_ + +#define DEFAULT_RECOVERY -1 + +#define DEFAULT_RECVOLUMES -10 + +enum PathExclMode { + EXCL_NONE,EXCL_BASEPATH,EXCL_SKIPWHOLEPATH,EXCL_SAVEFULLPATH, + EXCL_SKIPABSPATH,EXCL_ABSPATH +}; +enum {SOLID_NONE=0,SOLID_NORMAL=1,SOLID_COUNT=2,SOLID_FILEEXT=4, + SOLID_VOLUME_DEPENDENT=8,SOLID_VOLUME_INDEPENDENT=16}; +enum {ARCTIME_NONE,ARCTIME_KEEP,ARCTIME_LATEST}; +enum EXTTIME_MODE { + EXTTIME_NONE,EXTTIME_1S,EXTTIME_HIGH1,EXTTIME_HIGH2,EXTTIME_HIGH3 +}; +enum {NAMES_ORIGINALCASE,NAMES_UPPERCASE,NAMES_LOWERCASE}; +enum MESSAGE_TYPE {MSG_STDOUT,MSG_STDERR,MSG_ERRONLY,MSG_NULL}; +enum OVERWRITE_MODE { OVERWRITE_ASK,OVERWRITE_ALL,OVERWRITE_NONE}; + +#define MAX_FILTERS 16 +enum FilterState {FILTER_DEFAULT=0,FILTER_AUTO,FILTER_FORCE,FILTER_DISABLE}; + + +struct FilterMode +{ + FilterState State; + int Param1; + int Param2; +}; + + +class RAROptions +{ + public: + RAROptions(); + ~RAROptions(); + void Init(); + + uint ExclFileAttr; + uint InclFileAttr; + bool InclAttrSet; + uint WinSize; + char TempPath[NM]; + char SFXModule[NM]; + char ExtrPath[NM]; + wchar ExtrPathW[NM]; + char CommentFile[NM]; + char ArcPath[NM]; + char Password[MAXPASSWORD]; + bool EncryptHeaders; + char LogName[NM]; + MESSAGE_TYPE MsgStream; + bool Sound; + OVERWRITE_MODE Overwrite; + int Method; + int Recovery; + int RecVolNumber; + bool DisablePercentage; + bool DisableCopyright; + bool DisableDone; + int Solid; + int SolidCount; + bool ClearArc; + bool AddArcOnly; + bool AV; + bool DisableComment; + bool FreshFiles; + bool UpdateFiles; + PathExclMode ExclPath; + int Recurse; + Int64 VolSize; + Array<Int64> NextVolSizes; + int CurVolNum; + bool AllYes; + bool DisableViewAV; + bool DisableSortSolid; + int ArcTime; + int ConvertNames; + bool ProcessOwners; + bool SaveLinks; + int Priority; + int SleepTime; + bool KeepBroken; + bool EraseDisk; + bool OpenShared; + bool ExclEmptyDir; + bool DeleteFiles; + bool SyncFiles; + bool GenerateArcName; + char GenerateMask[80]; + bool ProcessEA; + bool SaveStreams; + bool SetCompressedAttr; + uint FileTimeOlder; + uint FileTimeNewer; + RarTime FileTimeBefore; + RarTime FileTimeAfter; + bool OldNumbering; + bool Lock; + bool Test; + bool VolumePause; + FilterMode FilterModes[MAX_FILTERS]; + char EmailTo[NM]; + int VersionControl; + bool NoEndBlock; + bool AppendArcNameToPath; + bool Shutdown; + EXTTIME_MODE xmtime; + EXTTIME_MODE xctime; + EXTTIME_MODE xatime; + EXTTIME_MODE xarctime; + char CompressStdin[NM]; + + + +#ifdef RARDLL + char DllDestName[NM]; + wchar DllDestNameW[NM]; + int DllOpMode; + int DllError; + LONG UserData; + UNRARCALLBACK Callback; + CHANGEVOLPROC ChangeVolProc; + PROCESSDATAPROC ProcessDataProc; +#endif +}; +#endif diff --git a/7zip/Compress/Rar29/Original/os.hpp b/7zip/Compress/Rar29/Original/os.hpp new file mode 100755 index 00000000..29da46a1 --- /dev/null +++ b/7zip/Compress/Rar29/Original/os.hpp @@ -0,0 +1,235 @@ +#ifndef _RAR_OS_ +#define _RAR_OS_ + +#define FALSE 0 +#define TRUE 1 + +#ifdef __EMX__ + #define INCL_BASE +#endif + +#if defined(_WIN_32) || defined(_EMX) +#define ENABLE_BAD_ALLOC +#endif + + +#if defined(_WIN_32) || defined(_EMX) + +#define LITTLE_ENDIAN +#define NM 1024 + +#ifdef _WIN_32 + +// Igor Pavlov +#ifndef STRICT +#define STRICT +#endif + +#undef WINVER +#undef _WIN32_WINNT +#define WINVER 0x0400 +#define _WIN32_WINNT 0x0300 + +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> +#include <prsht.h> + +#ifndef _WIN_CE +#include <winioctl.h> +#endif + +#endif + +#ifndef _WIN_CE +#include <sys/types.h> +#include <sys/stat.h> +#include <dos.h> +#endif + +#if !defined(_EMX) && !defined(_MSC_VER) && !defined(_WIN_CE) + #define ENABLE_MKTEMP + #include <dir.h> +#endif +#ifdef _MSC_VER + #define for if (0) ; else for +#ifndef _WIN_CE + #include <direct.h> +#endif +#else + #include <dirent.h> +#endif + +#ifndef _WIN_CE +#include <share.h> +#endif + +#if defined(ENABLE_BAD_ALLOC) && !defined(_WIN_CE) + #include <new.h> +#endif + +#ifdef _EMX + #include <unistd.h> + #include <pwd.h> + #include <grp.h> + #include <errno.h> + #ifdef _DJGPP + #include <utime.h> + #else + #include <os2.h> + #include <sys/utime.h> + #include <emx/syscalls.h> + #endif +#else + #if defined(_MSC_VER) || defined(__MINGW32__) + #include <exception> + #else + #include <except.h> + #endif +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#ifndef _WIN_CE + #include <fcntl.h> + #include <dos.h> + #include <io.h> + #include <time.h> + #include <signal.h> +#endif + +/* +#ifdef _WIN_32 +#pragma hdrstop +#endif +*/ + +#define ENABLE_ACCESS + +#define DefConfigName "rar.ini" +#define DefLogName "rar.log" + + +#define PATHDIVIDER "\\" +#define PATHDIVIDERW L"\\" +#define CPATHDIVIDER '\\' +#define MASKALL "*" +#define MASKALLW L"*" + +#define READBINARY "rb" +#define READTEXT "rt" +#define UPDATEBINARY "r+b" +#define CREATEBINARY "w+b" +#define APPENDTEXT "at" + +#if defined(_WIN_32) + #ifdef _MSC_VER + #define _stdfunction __cdecl + #else + #define _stdfunction _USERENTRY + #endif +#else + #define _stdfunction +#endif + +#endif + +#ifdef _UNIX + +#define NM 1024 + +#ifdef _BEOS +#include <be/kernel/fs_info.h> +#include <be/kernel/fs_attr.h> +#endif + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#if defined(__QNXNTO__) + #include <sys/param.h> +#endif +#if defined(__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined(__APPLE__) + #include <sys/param.h> + #include <sys/mount.h> +#else +#endif +#include <pwd.h> +#include <grp.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <fcntl.h> +#include <errno.h> +#include <dirent.h> +#include <time.h> +#include <signal.h> +#include <utime.h> +#include <locale.h> + +#ifdef S_IFLNK +#define SAVE_LINKS +#endif + +#define ENABLE_ACCESS + +#define DefConfigName ".rarrc" +#define DefLogName ".rarlog" + + +#define PATHDIVIDER "/" +#define PATHDIVIDERW L"/" +#define CPATHDIVIDER '/' +#define MASKALL "*" +#define MASKALLW L"*" + +#define READBINARY "r" +#define READTEXT "r" +#define UPDATEBINARY "r+" +#define CREATEBINARY "w+" +#define APPENDTEXT "a" + +#define _stdfunction + +#ifdef _APPLE + #ifndef BIG_ENDIAN + #define BIG_ENDIAN + #endif + #ifdef LITTLE_ENDIAN + #undef LITTLE_ENDIAN + #endif +#endif + +#if defined(__sparc) || defined(sparc) || defined(__hpux) + #ifndef BIG_ENDIAN + #define BIG_ENDIAN + #endif +#endif + +#endif + +typedef const char* MSGID; + +#define safebuf static + +#if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) + #if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN + #undef LITTLE_ENDIAN + #elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN + #undef BIG_ENDIAN + #else + #error "Both LITTLE_ENDIAN and BIG_ENDIAN are defined. Undef something one" + #endif +#endif + +#if !defined(BIG_ENDIAN) && !defined(_WIN_CE) && defined(_WIN_32) +#define ALLOW_NOT_ALIGNED_INT +#endif + +#endif // _RAR_OS_ diff --git a/7zip/Compress/Rar29/Original/pathfn.hpp b/7zip/Compress/Rar29/Original/pathfn.hpp new file mode 100755 index 00000000..c6d2d9b9 --- /dev/null +++ b/7zip/Compress/Rar29/Original/pathfn.hpp @@ -0,0 +1,44 @@ +#ifndef _RAR_PATHFN_ +#define _RAR_PATHFN_ + +char* PointToName(const char *Path); +wchar* PointToName(const wchar *Path); +char* PointToLastChar(const char *Path); +char* ConvertPath(const char *SrcPath,char *DestPath); +wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath); +void SetExt(char *Name,const char *NewExt); +void SetExt(wchar *Name,const wchar *NewExt); +void SetSFXExt(char *SFXName); +void SetSFXExt(wchar *SFXName); +char *GetExt(const char *Name); +wchar *GetExt(const wchar *Name); +bool CmpExt(const char *Name,const char *Ext); +bool IsWildcard(const char *Str,const wchar *StrW=NULL); +bool IsPathDiv(int Ch); +bool IsDriveDiv(int Ch); +int GetPathDisk(const char *Path); +void AddEndSlash(char *Path); +void AddEndSlash(wchar *Path); +void GetFilePath(const char *FullName,char *Path); +void GetFilePath(const wchar *FullName,wchar *Path); +void RemoveNameFromPath(char *Path); +void RemoveNameFromPath(wchar *Path); +bool EnumConfigPaths(char *Path,int Number); +void GetConfigName(const char *Name,char *FullName,bool CheckExist); +char* GetVolNumPart(char *ArcName); +void NextVolumeName(char *ArcName,bool OldNumbering); +bool IsNameUsable(const char *Name); +void MakeNameUsable(char *Name,bool Extended); +char* UnixSlashToDos(char *SrcName,char *DestName=NULL,uint MaxLength=NM); +char* DosSlashToUnix(char *SrcName,char *DestName=NULL,uint MaxLength=NM); +bool IsFullPath(const char *Path); +bool IsDiskLetter(const char *Path); +void GetPathRoot(const char *Path,char *Root); +int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate); +char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering); +wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW); + + +inline char* GetOutputName(const char *Name) {return((char *)Name);}; + +#endif diff --git a/7zip/Compress/Rar29/Original/rar.hpp b/7zip/Compress/Rar29/Original/rar.hpp new file mode 100755 index 00000000..70b6826b --- /dev/null +++ b/7zip/Compress/Rar29/Original/rar.hpp @@ -0,0 +1,80 @@ +#ifndef _RAR_RARCOMMON_ +#define _RAR_RARCOMMON_ + +#include "raros.hpp" +#include "os.hpp" + + +#ifdef RARDLL +#include "dll.hpp" +#endif + +#ifndef _WIN_CE +#include "version.hpp" +#endif +#include "rartypes.hpp" +#include "rardefs.hpp" +#include "rarlang.hpp" +#include "int64.hpp" +#include "unicode.hpp" +#include "errhnd.hpp" +#include "array.hpp" +#include "timefn.hpp" +#include "headers.hpp" +#include "rarfn.hpp" +#include "pathfn.hpp" +#include "strfn.hpp" +#include "strlist.hpp" +#include "file.hpp" +#include "sha1.hpp" +#include "crc.hpp" +#include "rijndael.hpp" +#include "crypt.hpp" +#include "filefn.hpp" +#include "filestr.hpp" +#include "find.hpp" +#include "scantree.hpp" +#include "savepos.hpp" +#include "getbits.hpp" +#include "rdwrfn.hpp" +#include "options.hpp" +#include "archive.hpp" +#include "match.hpp" +#include "cmddata.hpp" +#include "filcreat.hpp" +#include "consio.hpp" +#include "system.hpp" +#include "isnt.hpp" +#include "log.hpp" +#include "rawread.hpp" +#include "encname.hpp" +#include "resource.hpp" +#include "compress.hpp" + + +#include "rarvm.hpp" +#include "model.hpp" + + +#include "unpack.hpp" + + +#include "extinfo.hpp" +#include "extract.hpp" + + + +#include "list.hpp" + + + +#include "rs.hpp" +#include "recvol.hpp" +#include "volume.hpp" +#include "smallfn.hpp" +#include "ulinks.hpp" + +#include "global.hpp" + + +#endif diff --git a/7zip/Compress/Rar29/Original/rardefs.hpp b/7zip/Compress/Rar29/Original/rardefs.hpp new file mode 100755 index 00000000..51661658 --- /dev/null +++ b/7zip/Compress/Rar29/Original/rardefs.hpp @@ -0,0 +1,21 @@ +#ifndef _RAR_DEFS_ +#define _RAR_DEFS_ + +#define Min(x,y) (((x)<(y)) ? (x):(y)) +#define Max(x,y) (((x)>(y)) ? (x):(y)) + +#define MAXPASSWORD 128 + +#define DefSFXName "default.sfx" +#define DefSortListName "rarfiles.lst" + +#ifndef FA_RDONLY + #define FA_RDONLY 0x01 + #define FA_HIDDEN 0x02 + #define FA_SYSTEM 0x04 + #define FA_LABEL 0x08 + #define FA_DIREC 0x10 + #define FA_ARCH 0x20 +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/rarfn.hpp b/7zip/Compress/Rar29/Original/rarfn.hpp new file mode 100755 index 00000000..05ffdbcf --- /dev/null +++ b/7zip/Compress/Rar29/Original/rarfn.hpp @@ -0,0 +1,7 @@ +#ifndef _RAR_FN_ +#define _RAR_FN_ + +void RARInitData(); + + +#endif diff --git a/7zip/Compress/Rar29/Original/rarlang.hpp b/7zip/Compress/Rar29/Original/rarlang.hpp new file mode 100755 index 00000000..6151d15a --- /dev/null +++ b/7zip/Compress/Rar29/Original/rarlang.hpp @@ -0,0 +1,10 @@ +#ifndef _RAR_LANG_ +#define _RAR_LANG_ + + #ifdef USE_RC + #include "rarres.hpp" + #else + #include "loclang.hpp" + #endif + +#endif diff --git a/7zip/Compress/Rar29/Original/raros.hpp b/7zip/Compress/Rar29/Original/raros.hpp new file mode 100755 index 00000000..e6867981 --- /dev/null +++ b/7zip/Compress/Rar29/Original/raros.hpp @@ -0,0 +1,41 @@ +#ifndef _RAR_RAROS_ +#define _RAR_RAROS_ + +#ifdef __EMX__ + #define _EMX +#endif + +#ifdef __DJGPP__ + #define _DJGPP + #define _EMX +#endif + +#if defined(__WIN32__) || defined(_WIN32) + #define _WIN_32 +#endif + +#ifdef _WIN32_WCE + #define _WIN_32 + #define _WIN_CE + #ifdef WM_FILECHANGEINFO + #define PC2002 + #else + #undef PC2002 + #endif +#endif + +#ifdef __BEOS__ + #define _UNIX + #define _BEOS +#endif + +#ifdef __APPLE__ + #define _UNIX + #define _APPLE +#endif + +#if !defined(_EMX) && !defined(_WIN_32) && !defined(_BEOS) && !defined(_APPLE) + #define _UNIX +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/rartypes.hpp b/7zip/Compress/Rar29/Original/rartypes.hpp new file mode 100755 index 00000000..9e4f640f --- /dev/null +++ b/7zip/Compress/Rar29/Original/rartypes.hpp @@ -0,0 +1,21 @@ +#ifndef _RAR_TYPES_ +#define _RAR_TYPES_ + +typedef unsigned char byte; //8 bits +typedef unsigned short ushort; //preferably 16 bits, but can be more +typedef unsigned int uint; //32 bits or more + +typedef unsigned int uint32; //32 bits exactly +typedef int sint32; //signed 32 bits exactly +#define PRESENT_INT32 + +#if defined(_WIN_32) || defined(__GNUC__) || defined(__sgi) || defined(_AIX) || defined(__sun) || defined(__hpux) +typedef wchar_t wchar; +#else +typedef ushort wchar; +#endif + +#define SHORT16(x) (sizeof(ushort)==2 ? (ushort)(x):((x)&0xffff)) +#define UINT32(x) (sizeof(uint32)==4 ? (uint32)(x):((x)&0xffffffff)) + +#endif diff --git a/7zip/Compress/Rar29/Original/rarvm.cpp b/7zip/Compress/Rar29/Original/rarvm.cpp new file mode 100755 index 00000000..09585f5a --- /dev/null +++ b/7zip/Compress/Rar29/Original/rarvm.cpp @@ -0,0 +1,1050 @@ +#include "rar.hpp" + +#include "rarvmtbl.cpp" + +RarVM::RarVM() +{ + Mem=NULL; +} + + +RarVM::~RarVM() +{ + delete[] Mem; +} + + +void RarVM::Init() +{ + if (Mem==NULL) + Mem=new byte[VM_MEMSIZE+4]; +} + + +inline uint RarVM::GetValue(bool ByteMode,uint *Addr) +{ + if (ByteMode) + return(*(byte *)Addr); + else + { +#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) + byte *B=(byte *)Addr; + return UINT32((uint)B[0]|((uint)B[1]<<8)|((uint)B[2]<<16)|((uint)B[3]<<24)); +#else + return UINT32(*Addr); +#endif + } +} + +#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) + #define GET_VALUE(ByteMode,Addr) GetValue(ByteMode,(uint *)Addr) +#else + #define GET_VALUE(ByteMode,Addr) ((ByteMode) ? (*(byte *)(Addr)):UINT32(*(uint *)(Addr))) +#endif + + +inline void RarVM::SetValue(bool ByteMode,uint *Addr,uint Value) +{ + if (ByteMode) + *(byte *)Addr=Value; + else + { +#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32) + ((byte *)Addr)[0]=(byte)Value; + ((byte *)Addr)[1]=(byte)(Value>>8); + ((byte *)Addr)[2]=(byte)(Value>>16); + ((byte *)Addr)[3]=(byte)(Value>>24); +#else + *(uint32 *)Addr=Value; +#endif + } +} + +#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32) + #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint *)Addr,Value) +#else + #define SET_VALUE(ByteMode,Addr,Value) ((ByteMode) ? (*(byte *)(Addr)=(Value)):(*(uint32 *)(Addr)=((uint32)(Value)))) +#endif + + +void RarVM::SetValue(uint *Addr,uint Value) +{ + SetValue(false,Addr,Value); +} + + +inline uint* RarVM::GetOperand(VM_PreparedOperand *CmdOp) +{ + if (CmdOp->Type==VM_OPREGMEM) + return((uint *)&Mem[(*CmdOp->Addr+CmdOp->Base)&VM_MEMMASK]); + else + return(CmdOp->Addr); +} + + +void RarVM::Execute(VM_PreparedProgram *Prg) +{ + memcpy(R,Prg->InitR,sizeof(Prg->InitR)); + unsigned int GlobalSize=Min(Prg->GlobalData.Size(),VM_GLOBALMEMSIZE); + if (GlobalSize) + memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize); + unsigned int StaticSize=Min(Prg->StaticData.Size(),VM_GLOBALMEMSIZE-GlobalSize); + if (StaticSize) + memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize); + + R[7]=VM_MEMSIZE; + Flags=0; + + VM_PreparedCommand *PreparedCode=Prg->AltCmd ? Prg->AltCmd:&Prg->Cmd[0]; + if (!ExecuteCode(PreparedCode,Prg->CmdCount)) + PreparedCode[0].OpCode=VM_RET; + uint NewBlockPos=GET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20])&VM_MEMMASK; + uint NewBlockSize=GET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x1c])&VM_MEMMASK; + if (NewBlockPos+NewBlockSize>=VM_MEMSIZE) + NewBlockPos=NewBlockSize=0; + Prg->FilteredData=Mem+NewBlockPos; + Prg->FilteredDataSize=NewBlockSize; + + Prg->GlobalData.Reset(); + uint DataSize=Min(GET_VALUE(false,(uint*)&Mem[VM_GLOBALMEMADDR+0x30]),VM_GLOBALMEMSIZE); + if (DataSize!=0) + { + Prg->GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE); + memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE); + } +} + + +#define SET_IP(IP) \ + if ((IP)>=CodeSize) \ + return(true); \ + if (--MaxOpCount<=0) \ + return(false); \ + Cmd=PreparedCode+(IP); + +bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize) +{ + int MaxOpCount=25000000; + VM_PreparedCommand *Cmd=PreparedCode; + while (1) + { + uint *Op1=GetOperand(&Cmd->Op1); + uint *Op2=GetOperand(&Cmd->Op2); + switch(Cmd->OpCode) + { +#ifndef NORARVM + case VM_MOV: + SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2)); + break; +#ifdef VM_OPTIMIZE + case VM_MOVB: + SET_VALUE(true,Op1,GET_VALUE(true,Op2)); + break; + case VM_MOVD: + SET_VALUE(false,Op1,GET_VALUE(false,Op2)); + break; +#endif + case VM_CMP: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS); + } + break; +#ifdef VM_OPTIMIZE + case VM_CMPB: + { + uint Value1=GET_VALUE(true,Op1); + uint Result=UINT32(Value1-GET_VALUE(true,Op2)); + Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS); + } + break; + case VM_CMPD: + { + uint Value1=GET_VALUE(false,Op1); + uint Result=UINT32(Value1-GET_VALUE(false,Op2)); + Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS); + } + break; +#endif + case VM_ADD: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:(Result<Value1)|(Result&VM_FS); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; +#ifdef VM_OPTIMIZE + case VM_ADDB: + SET_VALUE(true,Op1,GET_VALUE(true,Op1)+GET_VALUE(true,Op2)); + break; + case VM_ADDD: + SET_VALUE(false,Op1,GET_VALUE(false,Op1)+GET_VALUE(false,Op2)); + break; +#endif + case VM_SUB: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:(Result>Value1)|(Result&VM_FS); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; +#ifdef VM_OPTIMIZE + case VM_SUBB: + SET_VALUE(true,Op1,GET_VALUE(true,Op1)-GET_VALUE(true,Op2)); + break; + case VM_SUBD: + SET_VALUE(false,Op1,GET_VALUE(false,Op1)-GET_VALUE(false,Op2)); + break; +#endif + case VM_JZ: + if ((Flags & VM_FZ)!=0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_JNZ: + if ((Flags & VM_FZ)==0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_INC: + { + uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)+1); + SET_VALUE(Cmd->ByteMode,Op1,Result); + Flags=Result==0 ? VM_FZ:Result&VM_FS; + } + break; +#ifdef VM_OPTIMIZE + case VM_INCB: + SET_VALUE(true,Op1,GET_VALUE(true,Op1)+1); + break; + case VM_INCD: + SET_VALUE(false,Op1,GET_VALUE(false,Op1)+1); + break; +#endif + case VM_DEC: + { + uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)-1); + SET_VALUE(Cmd->ByteMode,Op1,Result); + Flags=Result==0 ? VM_FZ:Result&VM_FS; + } + break; +#ifdef VM_OPTIMIZE + case VM_DECB: + SET_VALUE(true,Op1,GET_VALUE(true,Op1)-1); + break; + case VM_DECD: + SET_VALUE(false,Op1,GET_VALUE(false,Op1)-1); + break; +#endif + case VM_JMP: + SET_IP(GET_VALUE(false,Op1)); + continue; + case VM_XOR: + { + uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)^GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:Result&VM_FS; + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_AND: + { + uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)&GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:Result&VM_FS; + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_OR: + { + uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)|GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:Result&VM_FS; + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_TEST: + { + uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)&GET_VALUE(Cmd->ByteMode,Op2)); + Flags=Result==0 ? VM_FZ:Result&VM_FS; + } + break; + case VM_JS: + if ((Flags & VM_FS)!=0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_JNS: + if ((Flags & VM_FS)==0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_JB: + if ((Flags & VM_FC)!=0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_JBE: + if ((Flags & (VM_FC|VM_FZ))!=0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_JA: + if ((Flags & (VM_FC|VM_FZ))==0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_JAE: + if ((Flags & VM_FC)==0) + { + SET_IP(GET_VALUE(false,Op1)); + continue; + } + break; + case VM_PUSH: + R[7]-=4; + SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],GET_VALUE(false,Op1)); + break; + case VM_POP: + SET_VALUE(false,Op1,GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK])); + R[7]+=4; + break; + case VM_CALL: + R[7]-=4; + SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Cmd-PreparedCode+1); + SET_IP(GET_VALUE(false,Op1)); + continue; + case VM_NOT: + SET_VALUE(Cmd->ByteMode,Op1,~GET_VALUE(Cmd->ByteMode,Op1)); + break; + case VM_SHL: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint Value2=GET_VALUE(Cmd->ByteMode,Op2); + uint Result=UINT32(Value1<<Value2); + Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1<<(Value2-1))&0x80000000 ? VM_FC:0); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_SHR: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint Value2=GET_VALUE(Cmd->ByteMode,Op2); + uint Result=UINT32(Value1>>Value2); + Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_SAR: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint Value2=GET_VALUE(Cmd->ByteMode,Op2); + uint Result=UINT32(((int)Value1)>>Value2); + Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_NEG: + { + uint Result=UINT32(-GET_VALUE(Cmd->ByteMode,Op1)); + Flags=Result==0 ? VM_FZ:VM_FC|(Result&VM_FS); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; +#ifdef VM_OPTIMIZE + case VM_NEGB: + SET_VALUE(true,Op1,-GET_VALUE(true,Op1)); + break; + case VM_NEGD: + SET_VALUE(false,Op1,-GET_VALUE(false,Op1)); + break; +#endif + case VM_PUSHA: + { + const int RegCount=sizeof(R)/sizeof(R[0]); + for (int I=0,SP=R[7]-4;I<RegCount;I++,SP-=4) + SET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK],R[I]); + R[7]-=RegCount*4; + } + break; + case VM_POPA: + { + const int RegCount=sizeof(R)/sizeof(R[0]); + for (uint I=0,SP=R[7];I<RegCount;I++,SP+=4) + R[7-I]=GET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK]); + } + break; + case VM_PUSHF: + R[7]-=4; + SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Flags); + break; + case VM_POPF: + Flags=GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]); + R[7]+=4; + break; + case VM_MOVZX: + SET_VALUE(false,Op1,GET_VALUE(true,Op2)); + break; + case VM_MOVSX: + SET_VALUE(false,Op1,(signed char)GET_VALUE(true,Op2)); + break; + case VM_XCHG: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2)); + SET_VALUE(Cmd->ByteMode,Op2,Value1); + } + break; + case VM_MUL: + { + uint Result=GET_VALUE(Cmd->ByteMode,Op1)*GET_VALUE(Cmd->ByteMode,Op2); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_DIV: + { + uint Divider=GET_VALUE(Cmd->ByteMode,Op2); + if (Divider!=0) + { + uint Result=GET_VALUE(Cmd->ByteMode,Op1)/Divider; + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + } + break; + case VM_ADC: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint FC=(Flags&VM_FC); + uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2)+FC); + Flags=Result==0 ? VM_FZ:(Result<Value1 || Result==Value1 && FC)|(Result&VM_FS); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; + case VM_SBB: + { + uint Value1=GET_VALUE(Cmd->ByteMode,Op1); + uint FC=(Flags&VM_FC); + uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)-FC); + Flags=Result==0 ? VM_FZ:(Result>Value1 || Result==Value1 && FC)|(Result&VM_FS); + SET_VALUE(Cmd->ByteMode,Op1,Result); + } + break; +#endif + case VM_RET: + if (R[7]>=VM_MEMSIZE) + return(true); + SET_IP(GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK])); + R[7]+=4; + continue; +#ifdef VM_STANDARDFILTERS + case VM_STANDARD: + ExecuteStandardFilter((VM_StandardFilters)Cmd->Op1.Data); + break; +#endif + case VM_PRINT: +#ifdef DEBUG + PrintState(Cmd-PreparedCode); +#endif + break; + } + Cmd++; + --MaxOpCount; + } +} + + +void RarVM::PrintState(uint IP) +{ +#if defined(DEBUG) && !defined(GUI) && !defined(SILENT) + mprintf("\n"); + for (int I=0;I<sizeof(R)/sizeof(R[0]);I++) + mprintf("R%d=%08X\t%s",I,R[I],I==3 ? "\n":""); + mprintf("\nIP=%08X\tFlags: C=%d S=%d",IP,(Flags & VM_FC)!=0,(Flags & VM_FS)!=0); + mprintf("\n"); +#endif +} + + +void RarVM::Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg) +{ + InitBitInput(); + memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE)); + + byte XorSum=0; + for (int I=1;I<CodeSize;I++) + XorSum^=Code[I]; + + faddbits(8); + + Prg->CmdCount=0; + if (XorSum==Code[0]) + { +#ifdef VM_STANDARDFILTERS + VM_StandardFilters FilterType=IsStandardFilter(Code,CodeSize); + if (FilterType!=VMSF_NONE) + { + Prg->Cmd.Add(1); + VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++]; + CurCmd->OpCode=VM_STANDARD; + CurCmd->Op1.Data=FilterType; + CurCmd->Op1.Addr=&CurCmd->Op1.Data; + CurCmd->Op2.Addr=&CurCmd->Op2.Data; + CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE; + CodeSize=0; + } +#endif + uint DataFlag=fgetbits(); + faddbits(1); + if (DataFlag&0x8000) + { + int DataSize=ReadData(*this)+1; + for (int I=0;InAddr<CodeSize && I<DataSize;I++) + { + Prg->StaticData.Add(1); + Prg->StaticData[I]=fgetbits()>>8; + faddbits(8); + } + } + while (InAddr<CodeSize) + { + Prg->Cmd.Add(1); + VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount]; + uint Data=fgetbits(); + if ((Data&0x8000)==0) + { + CurCmd->OpCode=(VM_Commands)(Data>>12); + faddbits(4); + } + else + { + CurCmd->OpCode=(VM_Commands)((Data>>10)-24); + faddbits(6); + } + if (VM_CmdFlags[CurCmd->OpCode] & VMCF_BYTEMODE) + { + // Igor Pavlov + CurCmd->ByteMode = ((fgetbits() >> 15) != 0); + + faddbits(1); + } + else + CurCmd->ByteMode=0; + CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE; + int OpNum=(VM_CmdFlags[CurCmd->OpCode] & VMCF_OPMASK); + CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL; + if (OpNum>0) + { + DecodeArg(CurCmd->Op1,CurCmd->ByteMode); + if (OpNum==2) + DecodeArg(CurCmd->Op2,CurCmd->ByteMode); + else + { + if (CurCmd->Op1.Type==VM_OPINT && (VM_CmdFlags[CurCmd->OpCode]&(VMCF_JUMP|VMCF_PROC))) + { + int Distance=CurCmd->Op1.Data; + if (Distance>=256) + Distance-=256; + else + { + if (Distance>=136) + Distance-=264; + else + if (Distance>=16) + Distance-=8; + else + if (Distance>=8) + Distance-=16; + Distance+=Prg->CmdCount; + } + CurCmd->Op1.Data=Distance; + } + } + } + Prg->CmdCount++; + } + } + Prg->Cmd.Add(1); + VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++]; + CurCmd->OpCode=VM_RET; + CurCmd->Op1.Addr=&CurCmd->Op1.Data; + CurCmd->Op2.Addr=&CurCmd->Op2.Data; + CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE; + + for (int I=0;I<Prg->CmdCount;I++) + { + VM_PreparedCommand *Cmd=&Prg->Cmd[I]; + if (Cmd->Op1.Addr==NULL) + Cmd->Op1.Addr=&Cmd->Op1.Data; + if (Cmd->Op2.Addr==NULL) + Cmd->Op2.Addr=&Cmd->Op2.Data; + } + +#ifdef VM_OPTIMIZE + if (CodeSize!=0) + Optimize(Prg); +#endif +} + + +void RarVM::DecodeArg(VM_PreparedOperand &Op,bool ByteMode) +{ + uint Data=fgetbits(); + if (Data & 0x8000) + { + Op.Type=VM_OPREG; + Op.Data=(Data>>12)&7; + Op.Addr=&R[Op.Data]; + faddbits(4); + } + else + if ((Data & 0xc000)==0) + { + Op.Type=VM_OPINT; + if (ByteMode) + { + Op.Data=(Data>>6) & 0xff; + faddbits(10); + } + else + { + faddbits(2); + Op.Data=ReadData(*this); + } + } + else + { + Op.Type=VM_OPREGMEM; + if ((Data & 0x2000)==0) + { + Op.Data=(Data>>10)&7; + Op.Addr=&R[Op.Data]; + Op.Base=0; + faddbits(6); + } + else + { + if ((Data & 0x1000)==0) + { + Op.Data=(Data>>9)&7; + Op.Addr=&R[Op.Data]; + faddbits(7); + } + else + { + Op.Data=0; + faddbits(4); + } + Op.Base=ReadData(*this); + } + } +} + + +uint RarVM::ReadData(BitInput &Inp) +{ + uint Data=Inp.fgetbits(); + switch(Data&0xc000) + { + case 0: + Inp.faddbits(6); + return((Data>>10)&0xf); + case 0x4000: + if ((Data&0x3c00)==0) + { + Data=0xffffff00|((Data>>2)&0xff); + Inp.faddbits(14); + } + else + { + Data=(Data>>6)&0xff; + Inp.faddbits(10); + } + return(Data); + case 0x8000: + Inp.faddbits(2); + Data=Inp.fgetbits(); + Inp.faddbits(16); + return(Data); + default: + Inp.faddbits(2); + Data=(Inp.fgetbits()<<16); + Inp.faddbits(16); + Data|=Inp.fgetbits(); + Inp.faddbits(16); + return(Data); + } +} + + +void RarVM::SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize) +{ + if (Pos<VM_MEMSIZE && Data!=Mem+Pos) + memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos)); +} + + +#ifdef VM_OPTIMIZE +void RarVM::Optimize(VM_PreparedProgram *Prg) +{ + VM_PreparedCommand *Code=&Prg->Cmd[0]; + int CodeSize=Prg->CmdCount; + + for (int I=0;I<CodeSize;I++) + { + VM_PreparedCommand *Cmd=Code+I; + switch(Cmd->OpCode) + { + case VM_MOV: + Cmd->OpCode=Cmd->ByteMode ? VM_MOVB:VM_MOVD; + continue; + case VM_CMP: + Cmd->OpCode=Cmd->ByteMode ? VM_CMPB:VM_CMPD; + continue; + } + if ((VM_CmdFlags[Cmd->OpCode] & VMCF_CHFLAGS)==0) + continue; + bool FlagsRequired=false; + for (int J=I+1;J<CodeSize;J++) + { + int Flags=VM_CmdFlags[Code[J].OpCode]; + if (Flags & (VMCF_JUMP|VMCF_PROC|VMCF_USEFLAGS)) + { + FlagsRequired=true; + break; + } + if (Flags & VMCF_CHFLAGS) + break; + } + if (FlagsRequired) + continue; + switch(Cmd->OpCode) + { + case VM_ADD: + Cmd->OpCode=Cmd->ByteMode ? VM_ADDB:VM_ADDD; + continue; + case VM_SUB: + Cmd->OpCode=Cmd->ByteMode ? VM_SUBB:VM_SUBD; + continue; + case VM_INC: + Cmd->OpCode=Cmd->ByteMode ? VM_INCB:VM_INCD; + continue; + case VM_DEC: + Cmd->OpCode=Cmd->ByteMode ? VM_DECB:VM_DECD; + continue; + case VM_NEG: + Cmd->OpCode=Cmd->ByteMode ? VM_NEGB:VM_NEGD; + continue; + } + } +} +#endif + + +#ifdef VM_STANDARDFILTERS +VM_StandardFilters RarVM::IsStandardFilter(byte *Code,int CodeSize) +{ + struct StandardFilterSignature + { + int Length; + uint CRC; + VM_StandardFilters Type; + } StdList[]={ + 53, 0xad576887, VMSF_E8, + 57, 0x3cd7e57e, VMSF_E8E9, + 120, 0x3769893f, VMSF_ITANIUM, + 29, 0x0e06077d, VMSF_DELTA, + 149, 0x1c2c5dc8, VMSF_RGB, + 216, 0xbc85e701, VMSF_AUDIO, + 40, 0x46b9c560, VMSF_UPCASE + }; + uint CodeCRC=CRC(0xffffffff,Code,CodeSize)^0xffffffff; + for (int I=0;I<sizeof(StdList)/sizeof(StdList[0]);I++) + if (StdList[I].CRC==CodeCRC && StdList[I].Length==CodeSize) + return(StdList[I].Type); + return(VMSF_NONE); +} + + +void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType) +{ + switch(FilterType) + { + case VMSF_E8: + case VMSF_E8E9: + { + byte *Data=Mem; + int DataSize=R[4]; + uint FileOffset=R[6]; + + if (DataSize>=VM_GLOBALMEMADDR) + break; + + const int FileSize=0x1000000; + byte CmpByte2=FilterType==VMSF_E8E9 ? 0xe9:0xe8; + for (uint CurPos=0;CurPos<DataSize-4;) + { + byte CurByte=*(Data++); + CurPos++; + if (CurByte==0xe8 || CurByte==CmpByte2) + { +#ifdef PRESENT_INT32 + sint32 Offset=CurPos+FileOffset; + sint32 Addr=GET_VALUE(false,Data); + if (Addr<0) + { + if (Addr+Offset>=0) + SET_VALUE(false,Data,Addr+FileSize); + } + else + if (Addr<FileSize) + SET_VALUE(false,Data,Addr-Offset); +#else + long Offset=CurPos+FileOffset; + long Addr=GET_VALUE(false,Data); + if ((Addr & 0x80000000)!=0) + { + if (((Addr+Offset) & 0x80000000)==0) + SET_VALUE(false,Data,Addr+FileSize); + } + else + if (((Addr-FileSize) & 0x80000000)!=0) + SET_VALUE(false,Data,Addr-Offset); +#endif + Data+=4; + CurPos+=4; + } + } + } + break; + case VMSF_ITANIUM: + { + byte *Data=Mem; + int DataSize=R[4]; + uint FileOffset=R[6]; + + if (DataSize>=VM_GLOBALMEMADDR) + break; + + uint CurPos=0; + + FileOffset>>=4; + + while (CurPos<DataSize-21) + { + int Byte=(Data[0]&0x1f)-0x10; + if (Byte>=0) + { + static byte Masks[16]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0}; + byte CmdMask=Masks[Byte]; + if (CmdMask!=0) + for (int I=0;I<=2;I++) + if (CmdMask & (1<<I)) + { + int StartPos=I*41+5; + int OpType=FilterItanium_GetBits(Data,StartPos+37,4); + if (OpType==5) + { + int Offset=FilterItanium_GetBits(Data,StartPos+13,20); + FilterItanium_SetBits(Data,(Offset-FileOffset)&0xfffff,StartPos+13,20); + } + } + } + Data+=16; + CurPos+=16; + FileOffset++; + } + } + break; + case VMSF_DELTA: + { + int DataSize=R[4],Channels=R[0],SrcPos=0,Border=DataSize*2; + SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); + if (DataSize>=VM_GLOBALMEMADDR/2) + break; + for (int CurChannel=0;CurChannel<Channels;CurChannel++) + { + byte PrevByte=0; + for (int DestPos=DataSize+CurChannel;DestPos<Border;DestPos+=Channels) + Mem[DestPos]=(PrevByte-=Mem[SrcPos++]); + } + } + break; + case VMSF_RGB: + { + int DataSize=R[4],Width=R[0]-3,PosR=R[1]; + byte *SrcData=Mem,*DestData=SrcData+DataSize; + const int Channels=3; + SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); + if (DataSize>=VM_GLOBALMEMADDR/2) + break; + for (int CurChannel=0;CurChannel<Channels;CurChannel++) + { + unsigned int PrevByte=0; + + for (int I=CurChannel;I<DataSize;I+=Channels) + { + unsigned int Predicted; + int UpperPos=I-Width; + if (UpperPos>=3) + { + byte *UpperData=DestData+UpperPos; + unsigned int UpperByte=*UpperData; + unsigned int UpperLeftByte=*(UpperData-3); + Predicted=PrevByte+UpperByte-UpperLeftByte; + int pa=abs((int)(Predicted-PrevByte)); + int pb=abs((int)(Predicted-UpperByte)); + int pc=abs((int)(Predicted-UpperLeftByte)); + if (pa<=pb && pa<=pc) + Predicted=PrevByte; + else + if (pb<=pc) + Predicted=UpperByte; + else + Predicted=UpperLeftByte; + } + else + Predicted=PrevByte; + DestData[I]=PrevByte=(byte)(Predicted-*(SrcData++)); + } + } + for (int I=PosR,Border=DataSize-2;I<Border;I+=3) + { + byte G=DestData[I+1]; + DestData[I]+=G; + DestData[I+2]+=G; + } + } + break; + case VMSF_AUDIO: + { + int DataSize=R[4],Channels=R[0]; + byte *SrcData=Mem,*DestData=SrcData+DataSize; + SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); + if (DataSize>=VM_GLOBALMEMADDR/2) + break; + for (int CurChannel=0;CurChannel<Channels;CurChannel++) + { + unsigned int PrevByte=0,PrevDelta=0,Dif[7]; + int D1=0,D2=0,D3; + int K1=0,K2=0,K3=0; + memset(Dif,0,sizeof(Dif)); + + for (int I=CurChannel,ByteCount=0;I<DataSize;I+=Channels,ByteCount++) + { + D3=D2; + D2=PrevDelta-D1; + D1=PrevDelta; + + unsigned int Predicted=8*PrevByte+K1*D1+K2*D2+K3*D3; + Predicted=(Predicted>>3) & 0xff; + + unsigned int CurByte=*(SrcData++); + + Predicted-=CurByte; + DestData[I]=Predicted; + PrevDelta=(signed char)(Predicted-PrevByte); + PrevByte=Predicted; + + int D=((signed char)CurByte)<<3; + + Dif[0]+=abs(D); + Dif[1]+=abs(D-D1); + Dif[2]+=abs(D+D1); + Dif[3]+=abs(D-D2); + Dif[4]+=abs(D+D2); + Dif[5]+=abs(D-D3); + Dif[6]+=abs(D+D3); + + if ((ByteCount & 0x1f)==0) + { + unsigned int MinDif=Dif[0],NumMinDif=0; + Dif[0]=0; + for (int J=1;J<sizeof(Dif)/sizeof(Dif[0]);J++) + { + if (Dif[J]<MinDif) + { + MinDif=Dif[J]; + NumMinDif=J; + } + Dif[J]=0; + } + switch(NumMinDif) + { + case 1: if (K1>=-16) K1--; break; + case 2: if (K1 < 16) K1++; break; + case 3: if (K2>=-16) K2--; break; + case 4: if (K2 < 16) K2++; break; + case 5: if (K3>=-16) K3--; break; + case 6: if (K3 < 16) K3++; break; + } + } + } + } + } + break; + case VMSF_UPCASE: + { + int DataSize=R[4],SrcPos=0,DestPos=DataSize; + if (DataSize>=VM_GLOBALMEMADDR/2) + break; + while (SrcPos<DataSize) + { + byte CurByte=Mem[SrcPos++]; + if (CurByte==2 && (CurByte=Mem[SrcPos++])!=2) + CurByte-=32; + Mem[DestPos++]=CurByte; + } + SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x1c],DestPos-DataSize); + SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); + } + break; + } +} + + +unsigned int RarVM::FilterItanium_GetBits(byte *Data,int BitPos,int BitCount) +{ + int InAddr=BitPos/8; + int InBit=BitPos&7; + unsigned int BitField=(uint)Data[InAddr++]; + BitField|=(uint)Data[InAddr++] << 8; + BitField|=(uint)Data[InAddr++] << 16; + BitField|=(uint)Data[InAddr] << 24; + BitField >>= InBit; + return(BitField & (0xffffffff>>(32-BitCount))); +} + + +void RarVM::FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos, + int BitCount) +{ + int InAddr=BitPos/8; + int InBit=BitPos&7; + unsigned int AndMask=0xffffffff>>(32-BitCount); + AndMask=~(AndMask<<InBit); + + BitField<<=InBit; + + for (int I=0;I<4;I++) + { + Data[InAddr+I]&=AndMask; + Data[InAddr+I]|=BitField; + AndMask=(AndMask>>8)|0xff000000; + BitField>>=8; + } +} +#endif diff --git a/7zip/Compress/Rar29/Original/rarvm.hpp b/7zip/Compress/Rar29/Original/rarvm.hpp new file mode 100755 index 00000000..f330390b --- /dev/null +++ b/7zip/Compress/Rar29/Original/rarvm.hpp @@ -0,0 +1,110 @@ +#ifndef _RAR_VM_ +#define _RAR_VM_ + +#define VM_STANDARDFILTERS + +#ifndef SFX_MODULE +#define VM_OPTIMIZE +#endif + + +#define VM_MEMSIZE 0x40000 +#define VM_MEMMASK (VM_MEMSIZE-1) +#define VM_GLOBALMEMADDR 0x3C000 +#define VM_GLOBALMEMSIZE 0x2000 +#define VM_FIXEDGLOBALSIZE 64 + +enum VM_Commands +{ + VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC, + VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB, + VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT, + VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF, + VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT, + +#ifdef VM_OPTIMIZE + VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD, + + VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD, + VM_NEGB, VM_NEGD, +#endif + + VM_STANDARD +}; + +enum VM_StandardFilters { + VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO, + VMSF_DELTA, VMSF_UPCASE +}; + +enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000}; + +enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE}; + +struct VM_PreparedOperand +{ + VM_OpType Type; + uint Data; + uint Base; + uint *Addr; +}; + +struct VM_PreparedCommand +{ + VM_Commands OpCode; + bool ByteMode; + VM_PreparedOperand Op1,Op2; +}; + + +struct VM_PreparedProgram +{ + VM_PreparedProgram() {AltCmd=NULL;} + + Array<VM_PreparedCommand> Cmd; + VM_PreparedCommand *AltCmd; + int CmdCount; + + Array<byte> GlobalData; + Array<byte> StaticData; + uint InitR[7]; + + byte *FilteredData; + unsigned int FilteredDataSize; +}; + +class RarVM:private BitInput +{ + private: + inline uint GetValue(bool ByteMode,uint *Addr); + inline void SetValue(bool ByteMode,uint *Addr,uint Value); + inline uint* GetOperand(VM_PreparedOperand *CmdOp); + void PrintState(uint IP); + void DecodeArg(VM_PreparedOperand &Op,bool ByteMode); +#ifdef VM_OPTIMIZE + void Optimize(VM_PreparedProgram *Prg); +#endif + bool ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize); +#ifdef VM_STANDARDFILTERS + VM_StandardFilters IsStandardFilter(byte *Code,int CodeSize); + void ExecuteStandardFilter(VM_StandardFilters FilterType); + unsigned int FilterItanium_GetBits(byte *Data,int BitPos,int BitCount); + void FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos, + int BitCount); +#endif + + byte *Mem; + uint R[8]; + uint Flags; + public: + RarVM(); + ~RarVM(); + void Init(); + void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg); + void Execute(VM_PreparedProgram *Prg); + void SetValue(uint *Addr,uint Value); + void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize); + static uint ReadData(BitInput &Inp); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/rarvmtbl.cpp b/7zip/Compress/Rar29/Original/rarvmtbl.cpp new file mode 100755 index 00000000..b5e6c720 --- /dev/null +++ b/7zip/Compress/Rar29/Original/rarvmtbl.cpp @@ -0,0 +1,53 @@ +#define VMCF_OP0 0 +#define VMCF_OP1 1 +#define VMCF_OP2 2 +#define VMCF_OPMASK 3 +#define VMCF_BYTEMODE 4 +#define VMCF_JUMP 8 +#define VMCF_PROC 16 +#define VMCF_USEFLAGS 32 +#define VMCF_CHFLAGS 64 + +static byte VM_CmdFlags[]= +{ + /* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE , + /* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_JMP */ VMCF_OP1 | VMCF_JUMP , + /* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , + /* VM_PUSH */ VMCF_OP1 , + /* VM_POP */ VMCF_OP1 , + /* VM_CALL */ VMCF_OP1 | VMCF_PROC , + /* VM_RET */ VMCF_OP0 | VMCF_PROC , + /* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE , + /* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , + /* VM_PUSHA */ VMCF_OP0 , + /* VM_POPA */ VMCF_OP0 , + /* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS , + /* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS , + /* VM_MOVZX */ VMCF_OP2 , + /* VM_MOVSX */ VMCF_OP2 , + /* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE , + /* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE , + /* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE , + /* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS , + /* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS , + /* VM_PRINT */ VMCF_OP0 +}; diff --git a/7zip/Compress/Rar29/Original/rawread.hpp b/7zip/Compress/Rar29/Original/rawread.hpp new file mode 100755 index 00000000..47c2bbcb --- /dev/null +++ b/7zip/Compress/Rar29/Original/rawread.hpp @@ -0,0 +1,32 @@ +#ifndef _RAR_RAWREAD_ +#define _RAR_RAWREAD_ + +class RawRead +{ + private: + Array<byte> Data; + File *SrcFile; + int DataSize; + int ReadPos; +#ifndef SHELL_EXT + CryptData *Crypt; +#endif + public: + RawRead(File *SrcFile); + void Read(int Size); + void Read(byte *SrcData,int Size); + void Get(byte &Field); + void Get(ushort &Field); + void Get(uint &Field); + void Get8(Int64 &Field); + void Get(byte *Field,int Size); + void Get(wchar *Field,int Size); + uint GetCRC(bool ProcessedOnly); + int Size() {return DataSize;} + int PaddedSize() {return Data.Size()-DataSize;} +#ifndef SHELL_EXT + void SetCrypt(CryptData *Crypt) {RawRead::Crypt=Crypt;} +#endif +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/rdwrfn.cpp b/7zip/Compress/Rar29/Original/rdwrfn.cpp new file mode 100755 index 00000000..7340ea67 --- /dev/null +++ b/7zip/Compress/Rar29/Original/rdwrfn.cpp @@ -0,0 +1,306 @@ +#include "rar.hpp" + +// Igor Pavlov +#include "../../../Common/StreamUtils.h" + +ComprDataIO::ComprDataIO() +{ + Init(); +} + + +void ComprDataIO::Init() +{ + UnpackFromMemory=false; + UnpackToMemory=false; + UnpPackedSize=0; + ShowProgress=true; + TestMode=false; + SkipUnpCRC=false; + PackVolume=false; + UnpVolume=false; + NextVolumeMissing=false; + SrcFile=NULL; + DestFile=NULL; + UnpWrSize=0; + Command=NULL; + Encryption=0; + Decryption=0; + TotalPackRead=0; + CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0; + PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff; + LastPercent=-1; + // Igor Pavlov + /* + SubHead=NULL; + SubHeadPos=NULL; + */ + CurrentCommand=0; + ProcessedArcSize=TotalArcSize=0; +} + + + + +int ComprDataIO::UnpRead(byte *Addr,uint Count) +{ + int RetCode=0,TotalRead=0; + byte *ReadAddr; + ReadAddr=Addr; + while (Count > 0) + { + Archive *SrcArc=(Archive *)SrcFile; + + uint ReadSize=(Count>UnpPackedSize) ? int64to32(UnpPackedSize):Count; + if (UnpackFromMemory) + { + memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize); + RetCode=UnpackFromMemorySize; + UnpackFromMemorySize=0; + } + else + { + // Igor Pavlov + if (!SrcFile) + // if (!SrcFile->IsOpened()) + return(-1); + + // Igor Pavlov + UInt32 processedSize; + HRESULT result = ReadStream(SrcFile, ReadAddr, ReadSize, &processedSize); + RetCode = processedSize; + + // Igor Pavlov + /* + FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd; + if (hd->Flags & LHD_SPLIT_AFTER) + PackedCRC=CRC(PackedCRC,ReadAddr,ReadSize); + */ + } + CurUnpRead+=RetCode; + ReadAddr+=RetCode; + TotalRead+=RetCode; + Count-=RetCode; + UnpPackedSize-=RetCode; + if (UnpPackedSize == 0 && UnpVolume) + { +#ifndef NOVOLUME + if (!MergeArchive(*SrcArc,this,true,CurrentCommand)) +#endif + { + NextVolumeMissing=true; + return(-1); + } + } + else + break; + } + // Igor Pavlov + /* + Archive *SrcArc=(Archive *)SrcFile; + if (SrcArc!=NULL) + ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize); + */ + if (RetCode!=-1) + { + RetCode=TotalRead; +#ifndef NOCRYPT + if (Decryption) +#ifndef SFX_MODULE + if (Decryption<20) + Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE); + else + if (Decryption==20) + for (uint I=0;I<RetCode;I+=16) + Decrypt.DecryptBlock20(&Addr[I]); + else +#endif + { + int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16); + Decrypt.DecryptBlock(Addr,CryptSize); + } +#endif + } + Wait(); + return(RetCode); +} + + +void ComprDataIO::UnpWrite(byte *Addr,uint Count) +{ +#ifdef RARDLL + RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions(); + if (Cmd->DllOpMode!=RAR_SKIP) + { + if (Cmd->Callback!=NULL && + Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LONG)Addr,Count)==-1) + ErrHandler.Exit(USER_BREAK); + if (Cmd->ProcessDataProc!=NULL) + { +#ifdef _WIN_32 + _EBX=_ESP; +#endif + int RetCode=Cmd->ProcessDataProc(Addr,Count); +#ifdef _WIN_32 + _ESP=_EBX; +#endif + if (RetCode==0) + ErrHandler.Exit(USER_BREAK); + } + } +#endif + UnpWrAddr=Addr; + UnpWrSize=Count; + if (UnpackToMemory) + { + if (Count <= UnpackToMemorySize) + { + memcpy(UnpackToMemoryAddr,Addr,Count); + UnpackToMemoryAddr+=Count; + UnpackToMemorySize-=Count; + } + } + else + if (!TestMode) + { + // Igor Pavlov + // DestFile->Write(Addr,Count); + WriteStream(DestFile, Addr,Count, 0); + } + CurUnpWrite+=Count; + // Igor Pavlov + /* + if (!SkipUnpCRC) +#ifndef SFX_MODULE + if (((Archive *)SrcFile)->OldFormat) + UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count); + else +#endif + UnpFileCRC=CRC(UnpFileCRC,Addr,Count); + */ + ShowUnpWrite(); + Wait(); +} + + + + + + +void ComprDataIO::ShowUnpRead(Int64 ArcPos,Int64 ArcSize) +{ + if (ShowProgress && SrcFile!=NULL) + { + Archive *SrcArc=(Archive *)SrcFile; + RAROptions *Cmd=SrcArc->GetRAROptions(); + if (TotalArcSize!=0) + ArcSize=TotalArcSize; + ArcPos+=ProcessedArcSize; + if (!SrcArc->Volume) + { + int CurPercent=ToPercent(ArcPos,ArcSize); + if (!Cmd->DisablePercentage && CurPercent!=LastPercent) + { + mprintf("\b\b\b\b%3d%%",CurPercent); + LastPercent=CurPercent; + } + } + } +} + + +void ComprDataIO::ShowUnpWrite() +{ + // Igor Pavlov + if (Progress) + { + UInt64 unPackSize = CurUnpWrite; + HRESULT result = Progress->SetRatioInfo(NULL, &unPackSize); + if (result != S_OK) + throw CExitCode(result); + } +} + + + + + + + +// Igor Pavlov +/* +void ComprDataIO::SetFiles(File *SrcFile,File *DestFile) +{ + if (SrcFile!=NULL) + ComprDataIO::SrcFile=SrcFile; + if (DestFile!=NULL) + ComprDataIO::DestFile=DestFile; + LastPercent=-1; +} +*/ + +void ComprDataIO::GetUnpackedData(byte **Data,uint *Size) +{ + *Data=UnpWrAddr; + *Size=UnpWrSize; +} + +// Igor Pavlov +/* +void ComprDataIO::SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt) +{ + if (Encrypt) + { + Encryption=*Password ? Method:0; +#ifndef NOCRYPT + Crypt.SetCryptKeys(Password,Salt,Encrypt); +#endif + } + else + { + Decryption=*Password ? Method:0; +#ifndef NOCRYPT + Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29); +#endif + } +} + + +#ifndef SFX_MODULE +void ComprDataIO::SetAV15Encryption() +{ + Decryption=15; + Decrypt.SetAV15Encryption(); +} +#endif + + +#ifndef SFX_MODULE +void ComprDataIO::SetCmt13Encryption() +{ + Decryption=13; + Decrypt.SetCmt13Encryption(); +} +#endif + +*/ + + + +void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size) +{ + UnpackToMemory=true; + UnpackToMemoryAddr=Addr; + UnpackToMemorySize=Size; +} + +// Igor Pavlov +void ComprDataIO::SetFiles(ISequentialInStream *srcFile, + ISequentialOutStream *destFile, ICompressProgressInfo *progress) +{ + SrcFile = srcFile; + DestFile = destFile; + Progress = progress; + LastPercent = -1; +} + diff --git a/7zip/Compress/Rar29/Original/rdwrfn.hpp b/7zip/Compress/Rar29/Original/rdwrfn.hpp new file mode 100755 index 00000000..d2feb842 --- /dev/null +++ b/7zip/Compress/Rar29/Original/rdwrfn.hpp @@ -0,0 +1,104 @@ +#ifndef _RAR_DATAIO_ +#define _RAR_DATAIO_ + +// Igor Pavlov +#include "../../../ICoder.h" + +class CmdAdd; +class Unpack; + +// Igor Pavlov +struct CExitCode +{ + HRESULT Result; + CExitCode(HRESULT result): Result(result) {}; +}; + +class ComprDataIO +{ + private: + void ShowUnpRead(Int64 ArcPos,Int64 ArcSize); + void ShowUnpWrite(); + + + bool UnpackFromMemory; + uint UnpackFromMemorySize; + byte *UnpackFromMemoryAddr; + + bool UnpackToMemory; + uint UnpackToMemorySize; + byte *UnpackToMemoryAddr; + + uint UnpWrSize; + byte *UnpWrAddr; + + Int64 UnpPackedSize; + + bool ShowProgress; + bool TestMode; + bool SkipUnpCRC; + + // Igor Pavlov + // File *SrcFile; + // File *DestFile; + ISequentialInStream *SrcFile; + ISequentialOutStream *DestFile; + ICompressProgressInfo *Progress; + + CmdAdd *Command; + + // Igor Pavlov + /* + FileHeader *SubHead; + Int64 *SubHeadPos; + */ + +#ifndef NOCRYPT + CryptData Crypt; + CryptData Decrypt; +#endif + + + int LastPercent; + + char CurrentCommand; + + public: + ComprDataIO(); + void Init(); + int UnpRead(byte *Addr,uint Count); + void UnpWrite(byte *Addr,uint Count); + void EnableShowProgress(bool Show) {ShowProgress=Show;} + void GetUnpackedData(byte **Data,uint *Size); + void SetPackedSizeToRead(Int64 Size) {UnpPackedSize=Size;} + void SetTestMode(bool Mode) {TestMode=Mode;} + void SetSkipUnpCRC(bool Skip) {SkipUnpCRC=Skip;} + // Igor Pavlov + // void SetFiles(File *SrcFile,File *DestFile); + void SetFiles(ISequentialInStream *srcFile, + ISequentialOutStream *destFile, ICompressProgressInfo *progress); + + void SetCommand(CmdAdd *Cmd) {Command=Cmd;} + // Igor Pavlov + // void SetSubHeader(FileHeader *hd,Int64 *Pos) {SubHead=hd;SubHeadPos=Pos;} + // void SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt); + // void SetAV15Encryption(); + // void SetCmt13Encryption(); + void SetUnpackToMemory(byte *Addr,uint Size); + void SetCurrentCommand(char Cmd) {CurrentCommand=Cmd;} + + bool PackVolume; + bool UnpVolume; + bool NextVolumeMissing; + Int64 TotalPackRead; + Int64 UnpArcSize; + Int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite; + Int64 ProcessedArcSize,TotalArcSize; + + uint PackFileCRC,UnpFileCRC,PackedCRC; + + int Encryption; + int Decryption; +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/recvol.hpp b/7zip/Compress/Rar29/Original/recvol.hpp new file mode 100755 index 00000000..5a0abe58 --- /dev/null +++ b/7zip/Compress/Rar29/Original/recvol.hpp @@ -0,0 +1,16 @@ +#ifndef _RAR_RECVOL_ +#define _RAR_RECVOL_ + +class RecVolumes +{ + private: + File *SrcFile[256]; + Array<byte> Buf; + public: + RecVolumes(); + ~RecVolumes(); + void Make(RAROptions *Cmd,char *ArcName,wchar *ArcNameW); + bool Restore(RAROptions *Cmd,const char *Name,const wchar *NameW,bool Silent); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/resource.cpp b/7zip/Compress/Rar29/Original/resource.cpp new file mode 100755 index 00000000..f2a46573 --- /dev/null +++ b/7zip/Compress/Rar29/Original/resource.cpp @@ -0,0 +1,12 @@ +#include "rar.hpp" + + + +#if !defined(SILENT) || !defined(RARDLL) +const char *St(MSGID StringId) +{ + return(StringId); +} +#endif + + diff --git a/7zip/Compress/Rar29/Original/resource.hpp b/7zip/Compress/Rar29/Original/resource.hpp new file mode 100755 index 00000000..581b34b4 --- /dev/null +++ b/7zip/Compress/Rar29/Original/resource.hpp @@ -0,0 +1,14 @@ +#ifndef _RAR_RESOURCE_ +#define _RAR_RESOURCE_ + +#if defined(SILENT) && defined(RARDLL) +#define St(x) ("") +#else +const char *St(MSGID StringId); +#endif + + +inline const char *StT(MSGID StringId) {return(St(StringId));} + + +#endif diff --git a/7zip/Compress/Rar29/Original/rijndael.hpp b/7zip/Compress/Rar29/Original/rijndael.hpp new file mode 100755 index 00000000..6a8eddeb --- /dev/null +++ b/7zip/Compress/Rar29/Original/rijndael.hpp @@ -0,0 +1,37 @@ +#ifndef _RIJNDAEL_H_ +#define _RIJNDAEL_H_ + +/************************************************************************** + * This code is based on Szymon Stefanek AES implementation: * + * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz * + * * + * Dynamic tables generation is based on the Brian Gladman's work: * + * http://fp.gladman.plus.com/cryptography_technology/rijndael * + **************************************************************************/ + +#define _MAX_KEY_COLUMNS (256/32) +#define _MAX_ROUNDS 14 +#define MAX_IV_SIZE 16 + +class Rijndael +{ + public: + enum Direction { Encrypt , Decrypt }; + private: + void keySched(byte key[_MAX_KEY_COLUMNS][4]); + void keyEncToDec(); + void encrypt(const byte a[16], byte b[16]); + void decrypt(const byte a[16], byte b[16]); + void GenerateTables(); + + Direction m_direction; + byte m_initVector[MAX_IV_SIZE]; + byte m_expandedKey[_MAX_ROUNDS+1][4][4]; + public: + Rijndael(); + void init(Direction dir,const byte *key,byte *initVector); + int blockEncrypt(const byte *input, int inputLen, byte *outBuffer); + int blockDecrypt(const byte *input, int inputLen, byte *outBuffer); +}; + +#endif // _RIJNDAEL_H_ diff --git a/7zip/Compress/Rar29/Original/rs.hpp b/7zip/Compress/Rar29/Original/rs.hpp new file mode 100755 index 00000000..2f099f00 --- /dev/null +++ b/7zip/Compress/Rar29/Original/rs.hpp @@ -0,0 +1,32 @@ +#ifndef _RAR_RS_ +#define _RAR_RS_ + +#define MAXPAR 255 +#define MAXPOL 512 + +class RSCoder +{ + private: + void gfInit(); + int gfMult(int a,int b); + void pnInit(); + void pnMult(int *p1,int *p2,int *r); + + int gfExp[MAXPOL]; + int gfLog[MAXPAR+1]; + + int GXPol[MAXPOL*2]; + + int ErrorLocs[MAXPAR+1],ErrCount; + int Dn[MAXPAR+1]; + + int ParSize; + int PolB[MAXPOL]; + bool FirstBlockDone; + public: + RSCoder(int ParSize); + void Encode(byte *Data,int DataSize,byte *DestData); + bool Decode(byte *Data,int DataSize,int *EraLoc,int EraSize); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/savepos.hpp b/7zip/Compress/Rar29/Original/savepos.hpp new file mode 100755 index 00000000..303550a0 --- /dev/null +++ b/7zip/Compress/Rar29/Original/savepos.hpp @@ -0,0 +1,15 @@ +#ifndef _RAR_SAVEPOS_ +#define _RAR_SAVEPOS_ + +class SaveFilePos +{ + private: + File *SaveFile; + Int64 SavePos; + uint CloseCount; + public: + SaveFilePos(File &SaveFile); + ~SaveFilePos(); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/scantree.hpp b/7zip/Compress/Rar29/Original/scantree.hpp new file mode 100755 index 00000000..2f206ba1 --- /dev/null +++ b/7zip/Compress/Rar29/Original/scantree.hpp @@ -0,0 +1,52 @@ +#ifndef _RAR_SCANTREE_ +#define _RAR_SCANTREE_ + +enum { RECURSE_NONE=0,RECURSE_ALWAYS,RECURSE_WILDCARDS }; +enum { SCAN_SKIPDIRS=0,SCAN_GETDIRS,SCAN_GETDIRSTWICE,SCAN_GETCURDIRS }; +enum { SCAN_SUCCESS,SCAN_DONE,SCAN_ERROR,SCAN_NEXT }; + +#define MAXSCANDEPTH (NM/2) + +class CommandData; + +class ScanTree +{ + private: + bool PrepareMasks(); + int FindProc(FindData *FindData); + + FindFile *FindStack[MAXSCANDEPTH]; + int Depth; + + int SetAllMaskDepth; + + StringList *FileMasks; + int Recurse; + bool GetLinks; + int GetDirs; + int Errors; + + char CurMask[NM]; + wchar CurMaskW[NM]; + char OrigCurMask[NM]; + wchar OrigCurMaskW[NM]; + bool SearchAllInRoot; + bool FastFindFile; + int SpecPathLength; + int SpecPathLengthW; + + char ErrArcName[NM]; + + CommandData *Cmd; + public: + ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs); + ~ScanTree(); + int GetNext(FindData *FindData); + int GetSpecPathLength() {return(SpecPathLength);}; + int GetSpecPathLengthW() {return(SpecPathLengthW);}; + int GetErrors() {return(Errors);}; + void SetErrArcName(const char *Name) {strcpy(ErrArcName,Name);} + void SetCommandData(CommandData *Cmd) {ScanTree::Cmd=Cmd;} +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/sha1.hpp b/7zip/Compress/Rar29/Original/sha1.hpp new file mode 100755 index 00000000..96cef44e --- /dev/null +++ b/7zip/Compress/Rar29/Original/sha1.hpp @@ -0,0 +1,16 @@ +#ifndef _RAR_SHA1_ +#define _RAR_SHA1_ + +#define HW 5 + +typedef struct { + uint32 state[5]; + uint32 count[2]; + unsigned char buffer[64]; +} hash_context; + +void hash_initial( hash_context * c ); +void hash_process( hash_context * c, unsigned char * data, unsigned len ); +void hash_final( hash_context * c, uint32[HW] ); + +#endif diff --git a/7zip/Compress/Rar29/Original/smallfn.cpp b/7zip/Compress/Rar29/Original/smallfn.cpp new file mode 100755 index 00000000..094691f0 --- /dev/null +++ b/7zip/Compress/Rar29/Original/smallfn.cpp @@ -0,0 +1,17 @@ +#include "rar.hpp" + +int ToPercent(Int64 N1,Int64 N2) +{ + if (N2==0) + return(0); + if (N2<N1) + return(100); + return(int64to32(N1*100/N2)); +} + + +void RARInitData() +{ + InitCRC(); + ErrHandler.Clean(); +} diff --git a/7zip/Compress/Rar29/Original/smallfn.hpp b/7zip/Compress/Rar29/Original/smallfn.hpp new file mode 100755 index 00000000..096ffef1 --- /dev/null +++ b/7zip/Compress/Rar29/Original/smallfn.hpp @@ -0,0 +1,7 @@ +#ifndef _RAR_SMALLFN_ +#define _RAR_SMALLFN_ + +int ToPercent(Int64 N1,Int64 N2); +void RARInitData(); + +#endif diff --git a/7zip/Compress/Rar29/Original/strfn.hpp b/7zip/Compress/Rar29/Original/strfn.hpp new file mode 100755 index 00000000..57813e52 --- /dev/null +++ b/7zip/Compress/Rar29/Original/strfn.hpp @@ -0,0 +1,24 @@ +#ifndef _RAR_STRFN_ +#define _RAR_STRFN_ + +const char *NullToEmpty(const char *Str); +const wchar *NullToEmpty(const wchar *Str); +char *IntNameToExt(const char *Name); +void ExtToInt(const char *Src,char *Dest); +void IntToExt(const char *Src,char *Dest); +char* strlower(char *Str); +char* strupper(char *Str); +int stricomp(const char *Str1,const char *Str2); +int strnicomp(const char *Str1,const char *Str2,int N); +char* RemoveEOL(char *Str); +char* RemoveLF(char *Str); +unsigned int loctolower(byte ch); +unsigned int loctoupper(byte ch); + + + +bool LowAscii(const char *Str); +bool LowAscii(const wchar *Str); + + +#endif diff --git a/7zip/Compress/Rar29/Original/strlist.hpp b/7zip/Compress/Rar29/Original/strlist.hpp new file mode 100755 index 00000000..c4d3b017 --- /dev/null +++ b/7zip/Compress/Rar29/Original/strlist.hpp @@ -0,0 +1,39 @@ +#ifndef _RAR_STRLIST_ +#define _RAR_STRLIST_ + +class StringList +{ + private: + Array<char> StringData; + unsigned int CurPos; + + Array<wchar> StringDataW; + unsigned int CurPosW; + + Array<int> PosDataW; + uint PosDataItem; + + uint StringsCount; + + uint SaveCurPos[16],SaveCurPosW[16],SavePosDataItem[16],SavePosNumber; + public: + StringList(); + ~StringList(); + void Reset(); + unsigned int AddString(const char *Str); + unsigned int AddString(const char *Str,const wchar *StrW); + bool GetString(char *Str,int MaxLength); + bool GetString(char *Str,wchar *StrW,int MaxLength); + bool GetString(char *Str,wchar *StrW,int MaxLength,int StringNum); + char* GetString(); + bool GetString(char **Str,wchar **StrW); + char* GetString(unsigned int StringPos); + void Rewind(); + unsigned int ItemsCount() {return(StringsCount);}; + int GetBufferSize(); + bool Search(char *Str,wchar *StrW,bool CaseSensitive); + void SavePosition(); + void RestorePosition(); +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/suballoc.cpp b/7zip/Compress/Rar29/Original/suballoc.cpp new file mode 100755 index 00000000..bffc7632 --- /dev/null +++ b/7zip/Compress/Rar29/Original/suballoc.cpp @@ -0,0 +1,241 @@ +/**************************************************************************** + * This file is part of PPMd project * + * Written and distributed to public domain by Dmitry Shkarin 1997, * + * 1999-2000 * + * Contents: memory allocation routines * + ****************************************************************************/ + +SubAllocator::SubAllocator() +{ + Clean(); +} + + +void SubAllocator::Clean() +{ + SubAllocatorSize=0; +} + + +inline void SubAllocator::InsertNode(void* p,int indx) +{ + ((RAR_NODE*) p)->next=FreeList[indx].next; + FreeList[indx].next=(RAR_NODE*) p; +} + + +inline void* SubAllocator::RemoveNode(int indx) +{ + RAR_NODE* RetVal=FreeList[indx].next; + FreeList[indx].next=RetVal->next; + return RetVal; +} + + +inline uint SubAllocator::U2B(int NU) +{ + return /*8*NU+4*NU*/UNIT_SIZE*NU; +} + + +inline void SubAllocator::SplitBlock(void* pv,int OldIndx,int NewIndx) +{ + int i, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx]; + byte* p=((byte*) pv)+U2B(Indx2Units[NewIndx]); + if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff) + { + InsertNode(p,--i); + p += U2B(i=Indx2Units[i]); + UDiff -= i; + } + InsertNode(p,Units2Indx[UDiff-1]); +} + + + + +void SubAllocator::StopSubAllocator() +{ + if ( SubAllocatorSize ) + { + SubAllocatorSize=0; + rarfree(HeapStart); + } +} + + +bool SubAllocator::StartSubAllocator(int SASize) +{ + uint t=SASize << 20; + if (SubAllocatorSize == t) + return TRUE; + StopSubAllocator(); + uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+UNIT_SIZE; + if ((HeapStart=(byte *)rarmalloc(AllocSize)) == NULL) + { + ErrHandler.MemoryError(); + return FALSE; + } + HeapEnd=HeapStart+AllocSize-UNIT_SIZE; + SubAllocatorSize=t; + return TRUE; +} + + +void SubAllocator::InitSubAllocator() +{ + int i, k; + memset(FreeList,0,sizeof(FreeList)); + pText=HeapStart; + uint Size2=FIXED_UNIT_SIZE*(SubAllocatorSize/8/FIXED_UNIT_SIZE*7); + uint RealSize2=Size2/FIXED_UNIT_SIZE*UNIT_SIZE; + uint Size1=SubAllocatorSize-Size2; + uint RealSize1=Size1/FIXED_UNIT_SIZE*UNIT_SIZE+Size1%FIXED_UNIT_SIZE; + HiUnit=HeapStart+SubAllocatorSize; + LoUnit=UnitsStart=HeapStart+RealSize1; + FakeUnitsStart=HeapStart+Size1; + HiUnit=LoUnit+RealSize2; + for (i=0,k=1;i < N1 ;i++,k += 1) + Indx2Units[i]=k; + for (k++;i < N1+N2 ;i++,k += 2) + Indx2Units[i]=k; + for (k++;i < N1+N2+N3 ;i++,k += 3) + Indx2Units[i]=k; + for (k++;i < N1+N2+N3+N4;i++,k += 4) + Indx2Units[i]=k; + for (GlueCount=k=i=0;k < 128;k++) + { + i += (Indx2Units[i] < k+1); + Units2Indx[k]=i; + } +} + + +inline void SubAllocator::GlueFreeBlocks() +{ + RAR_MEM_BLK s0, * p, * p1; + int i, k, sz; + if (LoUnit != HiUnit) + *LoUnit=0; + for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++) + while ( FreeList[i].next ) + { + p=(RAR_MEM_BLK*)RemoveNode(i); + p->insertAt(&s0); + p->Stamp=0xFFFF; + p->NU=Indx2Units[i]; + } + for (p=s0.next;p != &s0;p=p->next) + while ((p1=p+p->NU)->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000) + { + p1->remove(); + p->NU += p1->NU; + } + while ((p=s0.next) != &s0) + { + for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p += 128) + InsertNode(p,N_INDEXES-1); + if (Indx2Units[i=Units2Indx[sz-1]] != sz) + { + k=sz-Indx2Units[--i]; + InsertNode(p+(sz-k),k-1); + } + InsertNode(p,i); + } +} + +void* SubAllocator::AllocUnitsRare(int indx) +{ + if ( !GlueCount ) + { + GlueCount = 255; + GlueFreeBlocks(); + if ( FreeList[indx].next ) + return RemoveNode(indx); + } + int i=indx; + do + { + if (++i == N_INDEXES) + { + GlueCount--; + i=U2B(Indx2Units[indx]); + int j=12*Indx2Units[indx]; + if (FakeUnitsStart-pText > j) + { + FakeUnitsStart-=j; + UnitsStart -= i; + return(UnitsStart); + } + return(NULL); + } + } while ( !FreeList[i].next ); + void* RetVal=RemoveNode(i); + SplitBlock(RetVal,i,indx); + return RetVal; +} + + +inline void* SubAllocator::AllocUnits(int NU) +{ + int indx=Units2Indx[NU-1]; + if ( FreeList[indx].next ) + return RemoveNode(indx); + void* RetVal=LoUnit; + LoUnit += U2B(Indx2Units[indx]); + if (LoUnit <= HiUnit) + return RetVal; + LoUnit -= U2B(Indx2Units[indx]); + return AllocUnitsRare(indx); +} + + +void* SubAllocator::AllocContext() +{ + if (HiUnit != LoUnit) + return (HiUnit -= UNIT_SIZE); + if ( FreeList->next ) + return RemoveNode(0); + return AllocUnitsRare(0); +} + + +void* SubAllocator::ExpandUnits(void* OldPtr,int OldNU) +{ + int i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1]; + if (i0 == i1) + return OldPtr; + void* ptr=AllocUnits(OldNU+1); + if ( ptr ) + { + memcpy(ptr,OldPtr,U2B(OldNU)); + InsertNode(OldPtr,i0); + } + return ptr; +} + + +void* SubAllocator::ShrinkUnits(void* OldPtr,int OldNU,int NewNU) +{ + int i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1]; + if (i0 == i1) + return OldPtr; + if ( FreeList[i1].next ) + { + void* ptr=RemoveNode(i1); + memcpy(ptr,OldPtr,U2B(NewNU)); + InsertNode(OldPtr,i0); + return ptr; + } + else + { + SplitBlock(OldPtr,i0,i1); + return OldPtr; + } +} + + +void SubAllocator::FreeUnits(void* ptr,int OldNU) +{ + InsertNode(ptr,Units2Indx[OldNU-1]); +} diff --git a/7zip/Compress/Rar29/Original/suballoc.hpp b/7zip/Compress/Rar29/Original/suballoc.hpp new file mode 100755 index 00000000..08174eea --- /dev/null +++ b/7zip/Compress/Rar29/Original/suballoc.hpp @@ -0,0 +1,81 @@ +/**************************************************************************** + * This file is part of PPMd project * + * Written and distributed to public domain by Dmitry Shkarin 1997, * + * 1999-2000 * + * Contents: interface to memory allocation routines * + ****************************************************************************/ +#if !defined(_SUBALLOC_H_) +#define _SUBALLOC_H_ + +const int N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; +const int N_INDEXES=N1+N2+N3+N4; + +#if defined(__GNUC__) +#define _PACK_ATTR __attribute__ ((packed)) +#else +#define _PACK_ATTR +#endif /* defined(__GNUC__) */ + +#pragma pack(1) +struct RAR_MEM_BLK +{ + ushort Stamp, NU; + RAR_MEM_BLK* next, * prev; + void insertAt(RAR_MEM_BLK* p) + { + next=(prev=p)->next; + p->next=next->prev=this; + } + void remove() + { + prev->next=next; + next->prev=prev; + } +} _PACK_ATTR; + +#ifdef _AIX +#pragma pack(pop) +#else +#pragma pack() +#endif + + +struct RAR_NODE +{ + RAR_NODE* next; +}; + +class SubAllocator +{ + private: + inline void InsertNode(void* p,int indx); + inline void* RemoveNode(int indx); + inline uint U2B(int NU); + inline void SplitBlock(void* pv,int OldIndx,int NewIndx); + uint GetUsedMemory(); + inline void GlueFreeBlocks(); + void* AllocUnitsRare(int indx); + + long SubAllocatorSize; + byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; + byte *HeapStart,*LoUnit, *HiUnit; + struct RAR_NODE FreeList[N_INDEXES]; + public: + SubAllocator(); + ~SubAllocator() {StopSubAllocator();} + void Clean(); + bool StartSubAllocator(int SASize); + void StopSubAllocator(); + void InitSubAllocator(); + inline void* AllocContext(); + inline void* AllocUnits(int NU); + inline void* ExpandUnits(void* ptr,int OldNU); + inline void* ShrinkUnits(void* ptr,int OldNU,int NewNU); + inline void FreeUnits(void* ptr,int OldNU); + long GetAllocatedMemory() {return(SubAllocatorSize);}; + + byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart; +}; + + +#endif /* !defined(_SUBALLOC_H_) */ diff --git a/7zip/Compress/Rar29/Original/system.cpp b/7zip/Compress/Rar29/Original/system.cpp new file mode 100755 index 00000000..1d3cdafe --- /dev/null +++ b/7zip/Compress/Rar29/Original/system.cpp @@ -0,0 +1,79 @@ +#include "rar.hpp" + +#ifndef _WIN_CE +static int SleepTime=0; + +void InitSystemOptions(int SleepTime) +{ + ::SleepTime=SleepTime; +} +#endif + + +#if !defined(SFX_MODULE) && !defined(_WIN_CE) + +#if defined(_WIN_32) && !defined(BELOW_NORMAL_PRIORITY_CLASS) +#define BELOW_NORMAL_PRIORITY_CLASS 0x00004000 +#define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 +#endif + +void SetPriority(int Priority) +{ +#ifdef _WIN_32 + uint PriorityClass; + int PriorityLevel; + if (Priority<1 || Priority>15) + return; + + if (Priority==1) + { + PriorityClass=IDLE_PRIORITY_CLASS; + PriorityLevel=THREAD_PRIORITY_IDLE; + } + else + if (Priority<7) + { + PriorityClass=IDLE_PRIORITY_CLASS; + PriorityLevel=Priority-4; + } + else + if (Priority==7) + { + PriorityClass=BELOW_NORMAL_PRIORITY_CLASS; + PriorityLevel=THREAD_PRIORITY_ABOVE_NORMAL; + } + else + if (Priority<10) + { + PriorityClass=NORMAL_PRIORITY_CLASS; + PriorityLevel=Priority-7; + } + else + if (Priority==10) + { + PriorityClass=ABOVE_NORMAL_PRIORITY_CLASS; + PriorityLevel=THREAD_PRIORITY_NORMAL; + } + else + { + PriorityClass=HIGH_PRIORITY_CLASS; + PriorityLevel=Priority-13; + } + SetPriorityClass(GetCurrentProcess(),PriorityClass); + SetThreadPriority(GetCurrentThread(),PriorityLevel); +#endif +} +#endif + + +void Wait() +{ +#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) + if (SleepTime!=0) + Sleep(SleepTime); +#endif +} + + + + diff --git a/7zip/Compress/Rar29/Original/system.hpp b/7zip/Compress/Rar29/Original/system.hpp new file mode 100755 index 00000000..89582ece --- /dev/null +++ b/7zip/Compress/Rar29/Original/system.hpp @@ -0,0 +1,10 @@ +#ifndef _RAR_SYSTEM_ +#define _RAR_SYSTEM_ + +void InitSystemOptions(int SleepTime); +void SetPriority(int Priority); +void Wait(); +bool EmailFile(char *FileName,char *MailTo); +void Shutdown(); + +#endif diff --git a/7zip/Compress/Rar29/Original/timefn.hpp b/7zip/Compress/Rar29/Original/timefn.hpp new file mode 100755 index 00000000..9ab5032f --- /dev/null +++ b/7zip/Compress/Rar29/Original/timefn.hpp @@ -0,0 +1,57 @@ +#ifndef _RAR_TIMEFN_ +#define _RAR_TIMEFN_ + +struct RarLocalTime +{ + uint Year; + uint Month; + uint Day; + uint Hour; + uint Minute; + uint Second; + uint Reminder; + uint wDay; + uint yDay; +}; + + +class RarTime +{ + private: + Int64 GetRaw(); + void SetRaw(Int64 RawTime); + + RarLocalTime rlt; + + Int64 Time; + public: + RarTime(); +#ifdef _WIN_32 + RarTime& operator =(FILETIME &ft); + void GetWin32(FILETIME *ft); +#endif +#if defined(_UNIX) || defined(_EMX) + RarTime& operator =(time_t ut); + time_t GetUnix(); +#endif + bool operator == (RarTime &rt); + bool operator < (RarTime &rt); + bool operator <= (RarTime &rt); + bool operator > (RarTime &rt); + bool operator >= (RarTime &rt); + void GetLocal(RarLocalTime *lt) {*lt=rlt;} + void SetLocal(RarLocalTime *lt) {rlt=*lt;} + uint GetDos(); + void SetDos(uint DosTime); + void GetText(char *DateStr,bool FullYear); + void SetIsoText(char *TimeText); + void SetAgeText(char *TimeText); + void SetCurrentTime(); + void Reset() {rlt.Year=0;} + bool IsSet() {return(rlt.Year!=0);} +}; + +const char *GetMonthName(int Month); +bool IsLeapYear(int Year); + +#endif diff --git a/7zip/Compress/Rar29/Original/ulinks.hpp b/7zip/Compress/Rar29/Original/ulinks.hpp new file mode 100755 index 00000000..69b0e9f8 --- /dev/null +++ b/7zip/Compress/Rar29/Original/ulinks.hpp @@ -0,0 +1,9 @@ +#ifndef _RAR_ULINKS_ +#define _RAR_ULINKS_ + +void SaveLinkData(ComprDataIO &DataIO,Archive &TempArc,FileHeader &hd, + char *Name); +int ExtractLink(ComprDataIO &DataIO,Archive &Arc,char *DestName, + uint &LinkCRC,bool Create); + +#endif diff --git a/7zip/Compress/Rar29/Original/unicode.hpp b/7zip/Compress/Rar29/Original/unicode.hpp new file mode 100755 index 00000000..a1bdbbe1 --- /dev/null +++ b/7zip/Compress/Rar29/Original/unicode.hpp @@ -0,0 +1,82 @@ +#ifndef _RAR_UNICODE_ +#define _RAR_UNICODE_ + +#ifndef _EMX +#define MBFUNCTIONS +#endif + +#if defined(MBFUNCTIONS) || defined(_WIN_32) || defined(_EMX) && !defined(_DJGPP) +#define UNICODE_SUPPORTED +#endif + +#ifdef _WIN_32 +#define DBCS_SUPPORTED +#endif + +#ifdef _EMX +int uni_init(int codepage); +int uni_done(); +#endif + +bool WideToChar(const wchar *Src,char *Dest,int DestSize=0x10000000); +bool CharToWide(const char *Src,wchar *Dest,int DestSize=0x10000000); +byte* WideToRaw(const wchar *Src,byte *Dest,int DestSize=0x10000000); +wchar* RawToWide(const byte *Src,wchar *Dest,int DestSize=0x10000000); +void WideToUtf(const wchar *Src,char *Dest,int DestSize); +void UtfToWide(const char *Src,wchar *Dest,int DestSize); +bool UnicodeEnabled(); + +int strlenw(const wchar *str); +wchar* strcpyw(wchar *dest,const wchar *src); +wchar* strncpyw(wchar *dest,const wchar *src,int n); +wchar* strcatw(wchar *dest,const wchar *src); +wchar* strncatw(wchar *dest,const wchar *src,int n); +int strcmpw(const wchar *s1,const wchar *s2); +int strncmpw(const wchar *s1,const wchar *s2,int n); +int stricmpw(const wchar *s1,const wchar *s2); +int strnicmpw(const wchar *s1,const wchar *s2,int n); +wchar *strchrw(const wchar *s,int c); +wchar* strrchrw(const wchar *s,int c); +wchar* strpbrkw(const wchar *s1,const wchar *s2); +wchar* strlowerw(wchar *Str); +wchar* strupperw(wchar *Str); +int toupperw(int ch); +int atoiw(const wchar *s); + +#ifdef DBCS_SUPPORTED +class SupportDBCS +{ + public: + SupportDBCS(); + void Init(); + + char* charnext(const char *s); + uint strlend(const char *s); + char *strchrd(const char *s, int c); + char *strrchrd(const char *s, int c); + void copychrd(char *dest,const char *src); + + bool IsLeadByte[256]; + bool DBCSMode; +}; + +extern SupportDBCS gdbcs; + +inline char* charnext(const char *s) {return (char *)(gdbcs.DBCSMode ? gdbcs.charnext(s):s+1);} +inline uint strlend(const char *s) {return (uint)(gdbcs.DBCSMode ? gdbcs.strlend(s):strlen(s));} +inline char* strchrd(const char *s, int c) {return (char *)(gdbcs.DBCSMode ? gdbcs.strchrd(s,c):strchr(s,c));} +inline char* strrchrd(const char *s, int c) {return (char *)(gdbcs.DBCSMode ? gdbcs.strrchrd(s,c):strrchr(s,c));} +inline void copychrd(char *dest,const char *src) {if (gdbcs.DBCSMode) gdbcs.copychrd(dest,src); else *dest=*src;} +inline bool IsDBCSMode() {return(gdbcs.DBCSMode);} +inline void InitDBCS() {gdbcs.Init();} + +#else +#define charnext(s) ((s)+1) +#define strlend strlen +#define strchrd strchr +#define strrchrd strrchr +#define IsDBCSMode() (true) +inline void copychrd(char *dest,const char *src) {*dest=*src;} +#endif + +#endif diff --git a/7zip/Compress/Rar29/Original/unpack.cpp b/7zip/Compress/Rar29/Original/unpack.cpp new file mode 100755 index 00000000..e72d83cf --- /dev/null +++ b/7zip/Compress/Rar29/Original/unpack.cpp @@ -0,0 +1,939 @@ +#include "rar.hpp" + +#include "coder.cpp" +#include "suballoc.cpp" +#include "model.cpp" +#ifndef SFX_MODULE +#include "unpack15.cpp" +// Igor Pavlov +// #include "unpack20.cpp" +#endif + +Unpack::Unpack(ComprDataIO *DataIO) +{ + UnpIO=DataIO; + Window=NULL; + ExternalWindow=false; + Suspended=false; + UnpAllBuf=false; + UnpSomeRead=false; +} + + +Unpack::~Unpack() +{ + if (Window!=NULL && !ExternalWindow) + delete[] Window; + InitFilters(); +} + + +void Unpack::Init(byte *Window) +{ + if (Window==NULL) + { + Unpack::Window=new byte[MAXWINSIZE]; +#ifndef ALLOW_EXCEPTIONS + if (Unpack::Window==NULL) + ErrHandler.MemoryError(); +#endif + } + else + { + Unpack::Window=Window; + ExternalWindow=true; + } + UnpInitData(false); +} + + +void Unpack::DoUnpack(int Method,bool Solid) +{ + switch(Method) + { +#ifndef SFX_MODULE + case 15: + Unpack15(Solid); + break; + // Igor Pavlov + /* + case 20: + case 26: + Unpack20(Solid); + break; + */ +#endif + case 29: + Unpack29(Solid); + break; + } +} + + +inline void Unpack::InsertOldDist(unsigned int Distance) +{ + OldDist[3]=OldDist[2]; + OldDist[2]=OldDist[1]; + OldDist[1]=OldDist[0]; + OldDist[0]=Distance; +} + + +inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance) +{ + LastDist=Distance; + LastLength=Length; +} + + +void Unpack::CopyString(unsigned int Length,unsigned int Distance) +{ + unsigned int DestPtr=UnpPtr-Distance; + if (DestPtr<MAXWINSIZE-260 && UnpPtr<MAXWINSIZE-260) + { + Window[UnpPtr++]=Window[DestPtr++]; + while (--Length>0) + Window[UnpPtr++]=Window[DestPtr++]; + } + else + while (Length--) + { + Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK]; + UnpPtr=(UnpPtr+1) & MAXWINMASK; + } +} + + +int Unpack::DecodeNumber(struct Decode *Dec) +{ + unsigned int Bits; + unsigned int BitField=getbits() & 0xfffe; + if (BitField<Dec->DecodeLen[8]) + if (BitField<Dec->DecodeLen[4]) + if (BitField<Dec->DecodeLen[2]) + if (BitField<Dec->DecodeLen[1]) + Bits=1; + else + Bits=2; + else + if (BitField<Dec->DecodeLen[3]) + Bits=3; + else + Bits=4; + else + if (BitField<Dec->DecodeLen[6]) + if (BitField<Dec->DecodeLen[5]) + Bits=5; + else + Bits=6; + else + if (BitField<Dec->DecodeLen[7]) + Bits=7; + else + Bits=8; + else + if (BitField<Dec->DecodeLen[12]) + if (BitField<Dec->DecodeLen[10]) + if (BitField<Dec->DecodeLen[9]) + Bits=9; + else + Bits=10; + else + if (BitField<Dec->DecodeLen[11]) + Bits=11; + else + Bits=12; + else + if (BitField<Dec->DecodeLen[14]) + if (BitField<Dec->DecodeLen[13]) + Bits=13; + else + Bits=14; + else + Bits=15; + + addbits(Bits); + unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits)); + if (N>=Dec->MaxNum) + N=0; + return(Dec->DecodeNum[N]); +} + + +void Unpack::Unpack29(bool Solid) +{ + static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; + static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; + static int DDecode[DC]; + static byte DBits[DC]; + static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12}; + static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; + static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6}; + unsigned int Bits; + + if (DDecode[1]==0) + { + int Dist=0,BitLength=0,Slot=0; + for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++) + for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength)) + { + DDecode[Slot]=Dist; + DBits[Slot]=BitLength; + } + } + + FileExtracted=true; + + if (!Suspended) + { + UnpInitData(Solid); + if (!UnpReadBuf()) + return; + if ((!Solid || !TablesRead) && !ReadTables()) + return; + } + + if (PPMError) + return; + + while (true) + { + UnpPtr&=MAXWINMASK; + + if (InAddr>ReadBorder) + { + if (!UnpReadBuf()) + break; + } + if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr) + { + UnpWriteBuf(); + if (WrittenFileSize>DestUnpSize) + return; + if (Suspended) + { + FileExtracted=false; + return; + } + } + if (UnpBlockType==BLOCK_PPM) + { + int Ch=PPM.DecodeChar(); + if (Ch==-1) + { + PPMError=true; + break; + } + if (Ch==PPMEscChar) + { + int NextCh=PPM.DecodeChar(); + if (NextCh==0) + { + if (!ReadTables()) + break; + continue; + } + if (NextCh==2 || NextCh==-1) + break; + if (NextCh==3) + { + if (!ReadVMCodePPM()) + break; + continue; + } + if (NextCh==4) + { + unsigned int Distance=0,Length; + bool Failed=false; + for (int I=0;I<4 && !Failed;I++) + { + int Ch=PPM.DecodeChar(); + if (Ch==-1) + Failed=true; + else + if (I==3) + Length=(byte)Ch; + else + Distance=(Distance<<8)+(byte)Ch; + } + if (Failed) + break; + CopyString(Length+32,Distance+2); + continue; + } + if (NextCh==5) + { + int Length=PPM.DecodeChar(); + if (Length==-1) + break; + CopyString(Length+4,1); + continue; + } + } + Window[UnpPtr++]=Ch; + continue; + } + + int Number=DecodeNumber((struct Decode *)&LD); + if (Number<256) + { + Window[UnpPtr++]=(byte)Number; + continue; + } + if (Number>=271) + { + int Length=LDecode[Number-=271]+3; + if ((Bits=LBits[Number])>0) + { + Length+=getbits()>>(16-Bits); + addbits(Bits); + } + + int DistNumber=DecodeNumber((struct Decode *)&DD); + unsigned int Distance=DDecode[DistNumber]+1; + if ((Bits=DBits[DistNumber])>0) + { + if (DistNumber>9) + { + if (Bits>4) + { + Distance+=((getbits()>>(20-Bits))<<4); + addbits(Bits-4); + } + if (LowDistRepCount>0) + { + LowDistRepCount--; + Distance+=PrevLowDist; + } + else + { + int LowDist=DecodeNumber((struct Decode *)&LDD); + if (LowDist==16) + { + LowDistRepCount=LOW_DIST_REP_COUNT-1; + Distance+=PrevLowDist; + } + else + { + Distance+=LowDist; + PrevLowDist=LowDist; + } + } + } + else + { + Distance+=getbits()>>(16-Bits); + addbits(Bits); + } + } + + if (Distance>=0x2000) + { + Length++; + if (Distance>=0x40000L) + Length++; + } + + InsertOldDist(Distance); + InsertLastMatch(Length,Distance); + CopyString(Length,Distance); + continue; + } + if (Number==256) + { + if (!ReadEndOfBlock()) + break; + continue; + } + if (Number==257) + { + if (!ReadVMCode()) + break; + continue; + } + if (Number==258) + { + if (LastLength!=0) + CopyString(LastLength,LastDist); + continue; + } + if (Number<263) + { + int DistNum=Number-259; + unsigned int Distance=OldDist[DistNum]; + for (int I=DistNum;I>0;I--) + OldDist[I]=OldDist[I-1]; + OldDist[0]=Distance; + + int LengthNumber=DecodeNumber((struct Decode *)&RD); + int Length=LDecode[LengthNumber]+2; + if ((Bits=LBits[LengthNumber])>0) + { + Length+=getbits()>>(16-Bits); + addbits(Bits); + } + InsertLastMatch(Length,Distance); + CopyString(Length,Distance); + continue; + } + if (Number<272) + { + unsigned int Distance=SDDecode[Number-=263]+1; + if ((Bits=SDBits[Number])>0) + { + Distance+=getbits()>>(16-Bits); + addbits(Bits); + } + InsertOldDist(Distance); + InsertLastMatch(2,Distance); + CopyString(2,Distance); + continue; + } + } + UnpWriteBuf(); +} + + +bool Unpack::ReadEndOfBlock() +{ + unsigned int BitField=getbits(); + bool NewTable,NewFile=false; + if (BitField & 0x8000) + { + NewTable=true; + addbits(1); + } + else + { + NewFile=true; + + // Igor Pavlov + NewTable = ((BitField & 0x4000) != 0); + + addbits(2); + } + TablesRead=!NewTable; + return !(NewFile || NewTable && !ReadTables()); +} + + +bool Unpack::ReadVMCode() +{ + unsigned int FirstByte=getbits()>>8; + addbits(8); + int Length=(FirstByte & 7)+1; + if (Length==7) + { + Length=(getbits()>>8)+7; + addbits(8); + } + else + if (Length==8) + { + Length=getbits(); + addbits(16); + } + Array<byte> VMCode(Length); + for (int I=0;I<Length;I++) + { + if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1) + return(false); + VMCode[I]=getbits()>>8; + addbits(8); + } + return(AddVMCode(FirstByte,&VMCode[0],Length)); +} + + +bool Unpack::ReadVMCodePPM() +{ + unsigned int FirstByte=PPM.DecodeChar(); + if ((int)FirstByte==-1) + return(false); + int Length=(FirstByte & 7)+1; + if (Length==7) + { + int B1=PPM.DecodeChar(); + if (B1==-1) + return(false); + Length=B1+7; + } + else + if (Length==8) + { + int B1=PPM.DecodeChar(); + if (B1==-1) + return(false); + int B2=PPM.DecodeChar(); + if (B2==-1) + return(false); + Length=B1*256+B2; + } + Array<byte> VMCode(Length); + for (int I=0;I<Length;I++) + { + int Ch=PPM.DecodeChar(); + if (Ch==-1) + return(false); + VMCode[I]=Ch; + } + return(AddVMCode(FirstByte,&VMCode[0],Length)); +} + + +bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize) +{ + BitInput Inp; + Inp.InitBitInput(); + memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize)); + VM.Init(); + + uint FiltPos; + if (FirstByte & 0x80) + { + FiltPos=RarVM::ReadData(Inp); + if (FiltPos==0) + InitFilters(); + else + FiltPos--; + } + else + FiltPos=LastFilter; + if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size()) + return(false); + LastFilter=FiltPos; + bool NewFilter=(FiltPos==Filters.Size()); + + UnpackFilter *Filter; + if (NewFilter) + { + Filters.Add(1); + Filters[Filters.Size()-1]=Filter=new UnpackFilter; + OldFilterLengths.Add(1); + Filter->ExecCount=0; + } + else + { + Filter=Filters[FiltPos]; + Filter->ExecCount++; + } + + UnpackFilter *StackFilter=new UnpackFilter; + + int EmptyCount=0; + for (int I=0;I<PrgStack.Size();I++) + { + PrgStack[I-EmptyCount]=PrgStack[I]; + if (PrgStack[I]==NULL) + EmptyCount++; + if (EmptyCount>0) + PrgStack[I]=NULL; + } + if (EmptyCount==0) + { + PrgStack.Add(1); + EmptyCount=1; + } + int StackPos=PrgStack.Size()-EmptyCount; + PrgStack[StackPos]=StackFilter; + StackFilter->ExecCount=Filter->ExecCount; + + uint BlockStart=RarVM::ReadData(Inp); + if (FirstByte & 0x40) + BlockStart+=258; + StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK; + if (FirstByte & 0x20) + StackFilter->BlockLength=RarVM::ReadData(Inp); + else + StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0; + StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart; + +// DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart); + + OldFilterLengths[FiltPos]=StackFilter->BlockLength; + + memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR)); + StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR; + StackFilter->Prg.InitR[4]=StackFilter->BlockLength; + StackFilter->Prg.InitR[5]=StackFilter->ExecCount; + if (FirstByte & 0x10) + { + unsigned int InitMask=Inp.fgetbits()>>9; + Inp.faddbits(7); + for (int I=0;I<7;I++) + if (InitMask & (1<<I)) + StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp); + } + if (NewFilter) + { + uint VMCodeSize=RarVM::ReadData(Inp); + if (VMCodeSize>=0x10000 || VMCodeSize==0) + return(false); + Array<byte> VMCode(VMCodeSize); + for (int I=0;I<VMCodeSize;I++) + { + VMCode[I]=Inp.fgetbits()>>8; + Inp.faddbits(8); + } + VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg); + } + StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0]; + StackFilter->Prg.CmdCount=Filter->Prg.CmdCount; + + int StaticDataSize=Filter->Prg.StaticData.Size(); + if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE) + { + StackFilter->Prg.StaticData.Add(StaticDataSize); + memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize); + } + + if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE) + { + StackFilter->Prg.GlobalData.Reset(); + StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE); + } + byte *GlobalData=&StackFilter->Prg.GlobalData[0]; + for (int I=0;I<7;I++) + VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]); + VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength); + VM.SetValue((uint *)&GlobalData[0x20],0); + VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount); + memset(&GlobalData[0x30],0,16); + + if (FirstByte & 8) + { + uint DataSize=RarVM::ReadData(Inp); + if (DataSize>=0x10000) + return(false); + unsigned int CurSize=StackFilter->Prg.GlobalData.Size(); + if (CurSize<DataSize+VM_FIXEDGLOBALSIZE) + StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize); + byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE]; + for (int I=0;I<DataSize;I++) + { + GlobalData[I]=Inp.fgetbits()>>8; + Inp.faddbits(8); + } + } + return(true); +} + + +bool Unpack::UnpReadBuf() +{ + int DataSize=ReadTop-InAddr; + if (DataSize<0) + return(false); + if (InAddr>BitInput::MAX_SIZE/2) + { + if (DataSize>0) + memmove(InBuf,InBuf+InAddr,DataSize); + InAddr=0; + ReadTop=DataSize; + } + else + DataSize=ReadTop; + int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf); + if (ReadCode>0) + ReadTop+=ReadCode; + ReadBorder=ReadTop-30; + return(ReadCode!=-1); +} + + +void Unpack::UnpWriteBuf() +{ + unsigned int WrittenBorder=WrPtr; + unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK; + for (int I=0;I<PrgStack.Size();I++) + { + UnpackFilter *flt=PrgStack[I]; + if (flt==NULL) + continue; + if (flt->NextWindow) + { + flt->NextWindow=false; + continue; + } + unsigned int BlockStart=flt->BlockStart; + unsigned int BlockLength=flt->BlockLength; + if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize) + { + if (WrittenBorder!=BlockStart) + { + UnpWriteArea(WrittenBorder,BlockStart); + WrittenBorder=BlockStart; + WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK; + } + if (BlockLength<=WriteSize) + { + unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK; + if (BlockStart<BlockEnd || BlockEnd==0) + VM.SetMemory(0,Window+BlockStart,BlockLength); + else + { + unsigned int FirstPartLength=MAXWINSIZE-BlockStart; + VM.SetMemory(0,Window+BlockStart,FirstPartLength); + VM.SetMemory(FirstPartLength,Window,BlockEnd); + } + VM_PreparedProgram *Prg=&flt->Prg; + ExecuteCode(Prg); + + byte *FilteredData=Prg->FilteredData; + unsigned int FilteredDataSize=Prg->FilteredDataSize; + + delete PrgStack[I]; + PrgStack[I]=NULL; + while (I+1<PrgStack.Size()) + { + UnpackFilter *NextFilter=PrgStack[I+1]; + if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart || + NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow) + break; + VM.SetMemory(0,FilteredData,FilteredDataSize); + VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg; + ExecuteCode(NextPrg); + FilteredData=NextPrg->FilteredData; + FilteredDataSize=NextPrg->FilteredDataSize; + I++; + delete PrgStack[I]; + PrgStack[I]=NULL; + } + UnpIO->UnpWrite(FilteredData,FilteredDataSize); + UnpSomeRead=true; + WrittenFileSize+=FilteredDataSize; + WrittenBorder=BlockEnd; + WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK; + } + else + { + for (int J=I;J<PrgStack.Size();J++) + { + UnpackFilter *flt=PrgStack[J]; + if (flt!=NULL && flt->NextWindow) + flt->NextWindow=false; + } + WrPtr=WrittenBorder; + return; + } + } + } + + UnpWriteArea(WrittenBorder,UnpPtr); + WrPtr=UnpPtr; +} + + +void Unpack::ExecuteCode(VM_PreparedProgram *Prg) +{ + if (Prg->GlobalData.Size()>0) + { + Prg->InitR[6]=int64to32(WrittenFileSize); + VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize)); + VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32)); + VM.Execute(Prg); + } +} + + +void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr) +{ + if (EndPtr!=StartPtr) + UnpSomeRead=true; + if (EndPtr<StartPtr) + { + UnpWriteData(&Window[StartPtr],-StartPtr & MAXWINMASK); + UnpWriteData(Window,EndPtr); + UnpAllBuf=true; + } + else + UnpWriteData(&Window[StartPtr],EndPtr-StartPtr); +} + + +void Unpack::UnpWriteData(byte *Data,int Size) +{ + if (WrittenFileSize>=DestUnpSize) + return; + int WriteSize=Size; + Int64 LeftToWrite=DestUnpSize-WrittenFileSize; + if (WriteSize>LeftToWrite) + WriteSize=int64to32(LeftToWrite); + UnpIO->UnpWrite(Data,WriteSize); + WrittenFileSize+=Size; +} + + +bool Unpack::ReadTables() +{ + byte BitLength[BC]; + unsigned char Table[HUFF_TABLE_SIZE]; + if (InAddr>ReadTop-25) + if (!UnpReadBuf()) + return(false); + faddbits((8-InBit)&7); + unsigned int BitField=fgetbits(); + if (BitField & 0x8000) + { + UnpBlockType=BLOCK_PPM; + return(PPM.DecodeInit(this,PPMEscChar)); + } + UnpBlockType=BLOCK_LZ; + + PrevLowDist=0; + LowDistRepCount=0; + + if (!(BitField & 0x4000)) + memset(UnpOldTable,0,sizeof(UnpOldTable)); + faddbits(2); + + for (int I=0;I<BC;I++) + { + int Length=(byte)(fgetbits() >> 12); + faddbits(4); + if (Length==15) + { + int ZeroCount=(byte)(fgetbits() >> 12); + faddbits(4); + if (ZeroCount==0) + BitLength[I]=15; + else + { + ZeroCount+=2; + while (ZeroCount-- > 0 && I<sizeof(BitLength)/sizeof(BitLength[0])) + BitLength[I++]=0; + I--; + } + } + else + BitLength[I]=Length; + } + MakeDecodeTables(BitLength,(struct Decode *)&BD,BC); + + const int TableSize=HUFF_TABLE_SIZE; + for (int I=0;I<TableSize;) + { + if (InAddr>ReadTop-5) + if (!UnpReadBuf()) + return(false); + int Number=DecodeNumber((struct Decode *)&BD); + if (Number<16) + { + Table[I]=(Number+UnpOldTable[I]) & 0xf; + I++; + } + else + if (Number<18) + { + int N; + if (Number==16) + { + N=(fgetbits() >> 13)+3; + faddbits(3); + } + else + { + N=(fgetbits() >> 9)+11; + faddbits(7); + } + while (N-- > 0 && I<TableSize) + { + Table[I]=Table[I-1]; + I++; + } + } + else + { + int N; + if (Number==18) + { + N=(fgetbits() >> 13)+3; + faddbits(3); + } + else + { + N=(fgetbits() >> 9)+11; + faddbits(7); + } + while (N-- > 0 && I<TableSize) + Table[I++]=0; + } + } + TablesRead=true; + if (InAddr>ReadTop) + return(false); + MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC); + MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC); + MakeDecodeTables(&Table[NC+DC],(struct Decode *)&LDD,LDC); + MakeDecodeTables(&Table[NC+DC+LDC],(struct Decode *)&RD,RC); + memcpy(UnpOldTable,Table,sizeof(UnpOldTable)); + return(true); +} + + +void Unpack::UnpInitData(int Solid) +{ + if (!Solid) + { + TablesRead=false; + memset(OldDist,0,sizeof(OldDist)); + OldDistPtr=0; + LastDist=LastLength=0; +// memset(Window,0,MAXWINSIZE); + memset(UnpOldTable,0,sizeof(UnpOldTable)); + UnpPtr=WrPtr=0; + PPMEscChar=2; + + InitFilters(); + } + InitBitInput(); + PPMError=false; + WrittenFileSize=0; + ReadTop=0; + ReadBorder=0; +#ifndef SFX_MODULE + // Igor Pavlov + // UnpInitData20(Solid); +#endif +} + + +void Unpack::InitFilters() +{ + OldFilterLengths.Reset(); + LastFilter=0; + + for (int I=0;I<Filters.Size();I++) + delete Filters[I]; + Filters.Reset(); + for (int I=0;I<PrgStack.Size();I++) + delete PrgStack[I]; + PrgStack.Reset(); +} + + +void Unpack::MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size) +{ + int LenCount[16],TmpPos[16],I; + long M,N; + memset(LenCount,0,sizeof(LenCount)); + memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum)); + for (I=0;I<Size;I++) + LenCount[LenTab[I] & 0xF]++; + + LenCount[0]=0; + for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++) + { + N=2*(N+LenCount[I]); + M=N<<(15-I); + if (M>0xFFFF) + M=0xFFFF; + Dec->DecodeLen[I]=(unsigned int)M; + TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1]; + } + + for (I=0;I<Size;I++) + if (LenTab[I]!=0) + Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I; + Dec->MaxNum=Size; +} diff --git a/7zip/Compress/Rar29/Original/unpack.hpp b/7zip/Compress/Rar29/Original/unpack.hpp new file mode 100755 index 00000000..83fb0f02 --- /dev/null +++ b/7zip/Compress/Rar29/Original/unpack.hpp @@ -0,0 +1,205 @@ +#ifndef _RAR_UNPACK_ +#define _RAR_UNPACK_ + +enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM}; + +struct Decode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[2]; +}; + +struct LitDecode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[NC]; +}; + +struct DistDecode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[DC]; +}; + +struct LowDistDecode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[LDC]; +}; + +struct RepDecode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[RC]; +}; + +struct BitDecode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[BC]; +}; + +struct UnpackFilter +{ + unsigned int BlockStart; + unsigned int BlockLength; + unsigned int ExecCount; + bool NextWindow; + VM_PreparedProgram Prg; +}; + +/***************************** Unpack v 2.0 *********************************/ +struct MultDecode +{ + unsigned int MaxNum; + unsigned int DecodeLen[16]; + unsigned int DecodePos[16]; + unsigned int DecodeNum[MC20]; +}; + +struct AudioVariables +{ + int K1,K2,K3,K4,K5; + int D1,D2,D3,D4; + int LastDelta; + unsigned int Dif[11]; + unsigned int ByteCount; + int LastChar; +}; +/***************************** Unpack v 2.0 *********************************/ + + +class Unpack:private BitInput +{ + private: + friend class Pack; + + void Unpack29(bool Solid); + bool UnpReadBuf(); + void UnpWriteBuf(); + void ExecuteCode(VM_PreparedProgram *Prg); + void UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr); + void UnpWriteData(byte *Data,int Size); + bool ReadTables(); + void MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size); + int DecodeNumber(struct Decode *Dec); + void CopyString(); + inline void InsertOldDist(unsigned int Distance); + inline void InsertLastMatch(unsigned int Length,unsigned int Distance); + void UnpInitData(int Solid); + void CopyString(unsigned int Length,unsigned int Distance); + bool ReadEndOfBlock(); + bool ReadVMCode(); + bool ReadVMCodePPM(); + bool AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize); + void InitFilters(); + + ComprDataIO *UnpIO; + ModelPPM PPM; + int PPMEscChar; + + RarVM VM; + Array<UnpackFilter*> Filters; + Array<UnpackFilter*> PrgStack; + Array<int> OldFilterLengths; + int LastFilter; + + bool TablesRead; + struct LitDecode LD; + struct DistDecode DD; + struct LowDistDecode LDD; + struct RepDecode RD; + struct BitDecode BD; + + unsigned int OldDist[4],OldDistPtr; + unsigned int LastDist,LastLength; + + unsigned int UnpPtr,WrPtr; + + int ReadTop; + int ReadBorder; + + unsigned char UnpOldTable[HUFF_TABLE_SIZE]; + + int UnpBlockType; + + byte *Window; + bool ExternalWindow; + + + Int64 DestUnpSize; + + bool Suspended; + bool UnpAllBuf; + bool UnpSomeRead; + Int64 WrittenFileSize; + bool FileExtracted; + bool PPMError; + + int PrevLowDist,LowDistRepCount; + +/***************************** Unpack v 1.5 *********************************/ + void Unpack15(bool Solid); + void ShortLZ(); + void LongLZ(); + void HuffDecode(); + void GetFlagsBuf(); + void OldUnpInitData(int Solid); + void InitHuff(); + void CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace); + void OldCopyString(unsigned int Distance,unsigned int Length); + unsigned int DecodeNum(int Num,unsigned int StartPos, + unsigned int *DecTab,unsigned int *PosTab); + void OldUnpWriteBuf(); + + unsigned int ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256]; + unsigned int Place[256],PlaceA[256],PlaceB[256],PlaceC[256]; + unsigned int NToPl[256],NToPlB[256],NToPlC[256]; + unsigned int FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3; + int Buf60,NumHuf,StMode,LCount,FlagsCnt; + unsigned int Nhfb,Nlzb,MaxDist3; +/***************************** Unpack v 1.5 *********************************/ + +/***************************** Unpack v 2.0 *********************************/ + void Unpack20(bool Solid); + struct MultDecode MD[4]; + unsigned char UnpOldTable20[MC20*4]; + int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta; + void CopyString20(unsigned int Length,unsigned int Distance); + bool ReadTables20(); + void UnpInitData20(int Solid); + void ReadLastTables(); + byte DecodeAudio(int Delta); + struct AudioVariables AudV[4]; +/***************************** Unpack v 2.0 *********************************/ + + public: + Unpack(ComprDataIO *DataIO); + ~Unpack(); + void Init(byte *Window=NULL); + void DoUnpack(int Method,bool Solid); + bool IsFileExtracted() {return(FileExtracted);} + void SetDestSize(Int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;} + void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;} + + unsigned int GetChar() + { + if (InAddr>BitInput::MAX_SIZE-30) + UnpReadBuf(); + return(InBuf[InAddr++]); + } +}; + +#endif diff --git a/7zip/Compress/Rar29/Original/unpack15.cpp b/7zip/Compress/Rar29/Original/unpack15.cpp new file mode 100755 index 00000000..a0fa897f --- /dev/null +++ b/7zip/Compress/Rar29/Original/unpack15.cpp @@ -0,0 +1,507 @@ +#define STARTL1 2 +static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00, + 0xee00,0xf000,0xf200,0xf200,0xffff}; +static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32}; + +#define STARTL2 3 +static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00, + 0xf000,0xf200,0xf240,0xffff}; +static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36}; + +#define STARTHF0 4 +static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200, + 0xf200,0xf200,0xffff}; +static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33}; + + +#define STARTHF1 5 +static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200, + 0xf7e0,0xffff}; +static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127}; + + +#define STARTHF2 5 +static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff, + 0xffff,0xffff}; +static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0}; + + +#define STARTHF3 6 +static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff, + 0xffff}; +static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0}; + + +#define STARTHF4 8 +static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff}; +static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0}; + + +void Unpack::Unpack15(bool Solid) +{ + if (Suspended) + UnpPtr=WrPtr; + else + { + UnpInitData(Solid); + OldUnpInitData(Solid); + UnpReadBuf(); + if (!Solid) + { + InitHuff(); + UnpPtr=0; + } + else + UnpPtr=WrPtr; + --DestUnpSize; + } + if (DestUnpSize>=0) + { + GetFlagsBuf(); + FlagsCnt=8; + } + + while (DestUnpSize>=0) + { + UnpPtr&=MAXWINMASK; + + if (InAddr>ReadTop-30 && !UnpReadBuf()) + break; + if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr) + { + OldUnpWriteBuf(); + if (Suspended) + return; + } + if (StMode) + { + HuffDecode(); + continue; + } + + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt=7; + } + + if (FlagBuf & 0x80) + { + FlagBuf<<=1; + if (Nlzb > Nhfb) + LongLZ(); + else + HuffDecode(); + } + else + { + FlagBuf<<=1; + if (--FlagsCnt < 0) + { + GetFlagsBuf(); + FlagsCnt=7; + } + if (FlagBuf & 0x80) + { + FlagBuf<<=1; + if (Nlzb > Nhfb) + HuffDecode(); + else + LongLZ(); + } + else + { + FlagBuf<<=1; + ShortLZ(); + } + } + } + OldUnpWriteBuf(); +} + + +void Unpack::OldUnpWriteBuf() +{ + if (UnpPtr!=WrPtr) + UnpSomeRead=true; + if (UnpPtr<WrPtr) + { + UnpIO->UnpWrite(&Window[WrPtr],-WrPtr & MAXWINMASK); + UnpIO->UnpWrite(Window,UnpPtr); + UnpAllBuf=true; + } + else + UnpIO->UnpWrite(&Window[WrPtr],UnpPtr-WrPtr); + WrPtr=UnpPtr; +} + + +void Unpack::ShortLZ() +{ + static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0}; + static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe, + 0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; + static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0}; + static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8, + 0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; + + + unsigned int Length,SaveLength; + unsigned int LastDistance; + unsigned int Distance; + int DistancePlace; + NumHuf=0; + + unsigned int BitField=fgetbits(); + if (LCount==2) + { + faddbits(1); + if (BitField >= 0x8000) + { + OldCopyString((unsigned int)LastDist,LastLength); + return; + } + BitField <<= 1; + LCount=0; + } + + BitField>>=8; + + ShortLen1[1]=ShortLen2[3]=Buf60+3; + + if (AvrLn1<37) + { + for (Length=0;;Length++) + if (((BitField^ShortXor1[Length]) & (~(0xff>>ShortLen1[Length])))==0) + break; + faddbits(ShortLen1[Length]); + } + else + { + for (Length=0;;Length++) + if (((BitField^ShortXor2[Length]) & (~(0xff>>ShortLen2[Length])))==0) + break; + faddbits(ShortLen2[Length]); + } + + if (Length >= 9) + { + if (Length == 9) + { + LCount++; + OldCopyString((unsigned int)LastDist,LastLength); + return; + } + if (Length == 14) + { + LCount=0; + Length=DecodeNum(fgetbits(),STARTL2,DecL2,PosL2)+5; + Distance=(fgetbits()>>1) | 0x8000; + faddbits(15); + LastLength=Length; + LastDist=Distance; + OldCopyString(Distance,Length); + return; + } + + LCount=0; + SaveLength=Length; + Distance=OldDist[(OldDistPtr-(Length-9)) & 3]; + Length=DecodeNum(fgetbits(),STARTL1,DecL1,PosL1)+2; + if (Length==0x101 && SaveLength==10) + { + Buf60 ^= 1; + return; + } + if (Distance > 256) + Length++; + if (Distance >= MaxDist3) + Length++; + + OldDist[OldDistPtr++]=Distance; + OldDistPtr = OldDistPtr & 3; + LastLength=Length; + LastDist=Distance; + OldCopyString(Distance,Length); + return; + } + + LCount=0; + AvrLn1 += Length; + AvrLn1 -= AvrLn1 >> 4; + + DistancePlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2) & 0xff; + Distance=ChSetA[DistancePlace]; + if (--DistancePlace != -1) + { + PlaceA[Distance]--; + LastDistance=ChSetA[DistancePlace]; + PlaceA[LastDistance]++; + ChSetA[DistancePlace+1]=LastDistance; + ChSetA[DistancePlace]=Distance; + } + Length+=2; + OldDist[OldDistPtr++] = ++Distance; + OldDistPtr = OldDistPtr & 3; + LastLength=Length; + LastDist=Distance; + OldCopyString(Distance,Length); +} + + +void Unpack::LongLZ() +{ + unsigned int Length; + unsigned int Distance; + unsigned int DistancePlace,NewDistancePlace; + unsigned int OldAvr2,OldAvr3; + + NumHuf=0; + Nlzb+=16; + if (Nlzb > 0xff) + { + Nlzb=0x90; + Nhfb >>= 1; + } + OldAvr2=AvrLn2; + + unsigned int BitField=fgetbits(); + if (AvrLn2 >= 122) + Length=DecodeNum(BitField,STARTL2,DecL2,PosL2); + else + if (AvrLn2 >= 64) + Length=DecodeNum(BitField,STARTL1,DecL1,PosL1); + else + if (BitField < 0x100) + { + Length=BitField; + faddbits(16); + } + else + { + for (Length=0;((BitField<<Length)&0x8000)==0;Length++) + ; + faddbits(Length+1); + } + + AvrLn2 += Length; + AvrLn2 -= AvrLn2 >> 5; + + BitField=fgetbits(); + if (AvrPlcB > 0x28ff) + DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); + else + if (AvrPlcB > 0x6ff) + DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1); + else + DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0); + + AvrPlcB += DistancePlace; + AvrPlcB -= AvrPlcB >> 8; + while (1) + { + Distance = ChSetB[DistancePlace & 0xff]; + NewDistancePlace = NToPlB[Distance++ & 0xff]++; + if (!(Distance & 0xff)) + CorrHuff(ChSetB,NToPlB); + else + break; + } + + ChSetB[DistancePlace]=ChSetB[NewDistancePlace]; + ChSetB[NewDistancePlace]=Distance; + + Distance=((Distance & 0xff00) | (fgetbits() >> 8)) >> 1; + faddbits(7); + + OldAvr3=AvrLn3; + if (Length!=1 && Length!=4) + if (Length==0 && Distance <= MaxDist3) + { + AvrLn3++; + AvrLn3 -= AvrLn3 >> 8; + } + else + if (AvrLn3 > 0) + AvrLn3--; + Length+=3; + if (Distance >= MaxDist3) + Length++; + if (Distance <= 256) + Length+=8; + if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40) + MaxDist3=0x7f00; + else + MaxDist3=0x2001; + OldDist[OldDistPtr++]=Distance; + OldDistPtr = OldDistPtr & 3; + LastLength=Length; + LastDist=Distance; + OldCopyString(Distance,Length); +} + + +void Unpack::HuffDecode() +{ + unsigned int CurByte,NewBytePlace; + unsigned int Length; + unsigned int Distance; + int BytePlace; + + unsigned int BitField=fgetbits(); + + if (AvrPlc > 0x75ff) + BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4); + else + if (AvrPlc > 0x5dff) + BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3); + else + if (AvrPlc > 0x35ff) + BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2); + else + if (AvrPlc > 0x0dff) + BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1); + else + BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0); + BytePlace&=0xff; + if (StMode) + { + if (BytePlace==0 && BitField > 0xfff) + BytePlace=0x100; + if (--BytePlace==-1) + { + BitField=fgetbits(); + faddbits(1); + if (BitField & 0x8000) + { + NumHuf=StMode=0; + return; + } + else + { + Length = (BitField & 0x4000) ? 4 : 3; + faddbits(1); + Distance=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2); + Distance = (Distance << 5) | (fgetbits() >> 11); + faddbits(5); + OldCopyString(Distance,Length); + return; + } + } + } + else + if (NumHuf++ >= 16 && FlagsCnt==0) + StMode=1; + AvrPlc += BytePlace; + AvrPlc -= AvrPlc >> 8; + Nhfb+=16; + if (Nhfb > 0xff) + { + Nhfb=0x90; + Nlzb >>= 1; + } + + Window[UnpPtr++]=(byte)(ChSet[BytePlace]>>8); + --DestUnpSize; + + while (1) + { + CurByte=ChSet[BytePlace]; + NewBytePlace=NToPl[CurByte++ & 0xff]++; + if ((CurByte & 0xff) > 0xa1) + CorrHuff(ChSet,NToPl); + else + break; + } + + ChSet[BytePlace]=ChSet[NewBytePlace]; + ChSet[NewBytePlace]=CurByte; +} + + +void Unpack::GetFlagsBuf() +{ + unsigned int Flags,NewFlagsPlace; + unsigned int FlagsPlace=DecodeNum(fgetbits(),STARTHF2,DecHf2,PosHf2); + + while (1) + { + Flags=ChSetC[FlagsPlace]; + FlagBuf=Flags>>8; + NewFlagsPlace=NToPlC[Flags++ & 0xff]++; + if ((Flags & 0xff) != 0) + break; + CorrHuff(ChSetC,NToPlC); + } + + ChSetC[FlagsPlace]=ChSetC[NewFlagsPlace]; + ChSetC[NewFlagsPlace]=Flags; +} + + +void Unpack::OldUnpInitData(int Solid) +{ + if (!Solid) + { + AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0; + AvrPlc=0x3500; + MaxDist3=0x2001; + Nhfb=Nlzb=0x80; + } + FlagsCnt=0; + FlagBuf=0; + StMode=0; + LCount=0; + ReadTop=0; +} + + +void Unpack::InitHuff() +{ + for (unsigned int I=0;I<256;I++) + { + Place[I]=PlaceA[I]=PlaceB[I]=I; + PlaceC[I]=(~I+1) & 0xff; + ChSet[I]=ChSetB[I]=I<<8; + ChSetA[I]=I; + ChSetC[I]=((~I+1) & 0xff)<<8; + } + memset(NToPl,0,sizeof(NToPl)); + memset(NToPlB,0,sizeof(NToPlB)); + memset(NToPlC,0,sizeof(NToPlC)); + CorrHuff(ChSetB,NToPlB); +} + + +void Unpack::CorrHuff(unsigned int *CharSet,unsigned int *NumToPlace) +{ + int I,J; + for (I=7;I>=0;I--) + for (J=0;J<32;J++,CharSet++) + *CharSet=(*CharSet & ~0xff) | I; + memset(NumToPlace,0,sizeof(NToPl)); + for (I=6;I>=0;I--) + NumToPlace[I]=(7-I)*32; +} + + +void Unpack::OldCopyString(unsigned int Distance,unsigned int Length) +{ + DestUnpSize-=Length; + while (Length--) + { + Window[UnpPtr]=Window[(UnpPtr-Distance) & MAXWINMASK]; + UnpPtr=(UnpPtr+1) & MAXWINMASK; + } +} + + +unsigned int Unpack::DecodeNum(int Num,unsigned int StartPos, + unsigned int *DecTab,unsigned int *PosTab) +{ + int I; + for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++) + StartPos++; + faddbits(StartPos); + return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]); +} diff --git a/7zip/Compress/Rar29/Original/version.hpp b/7zip/Compress/Rar29/Original/version.hpp new file mode 100755 index 00000000..6a5c653d --- /dev/null +++ b/7zip/Compress/Rar29/Original/version.hpp @@ -0,0 +1,6 @@ +#define RARVER_MAJOR 3 +#define RARVER_MINOR 50 +#define RARVER_BETA 0 +#define RARVER_DAY 3 +#define RARVER_MONTH 8 +#define RARVER_YEAR 2005 diff --git a/7zip/Compress/Rar29/Original/volume.hpp b/7zip/Compress/Rar29/Original/volume.hpp new file mode 100755 index 00000000..64653405 --- /dev/null +++ b/7zip/Compress/Rar29/Original/volume.hpp @@ -0,0 +1,11 @@ +#ifndef _RAR_VOLUME_ +#define _RAR_VOLUME_ + +void SplitArchive(Archive &Arc,FileHeader *fh,Int64 *HeaderPos, + ComprDataIO *DataIO); +bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName, + char Command); +void SetVolWrite(Archive &Dest,Int64 VolSize); +bool AskNextVol(char *ArcName); + +#endif diff --git a/7zip/Compress/Rar29/Rar29.dsp b/7zip/Compress/Rar29/Rar29.dsp new file mode 100755 index 00000000..7c3f3ba2 --- /dev/null +++ b/7zip/Compress/Rar29/Rar29.dsp @@ -0,0 +1,415 @@ +# Microsoft Developer Studio Project File - Name="Rar29" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Rar29 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "RAR29.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "RAR29.mak" CFG="Rar29 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Rar29 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Rar29 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Rar29.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAR29_EXPORTS" /D "SILENT" /D "NOCRYPT" /D "NOVOLUME" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-Zip\Codecs\Rar29.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Rar29 - Win32 Release" +# Name "Rar29 - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Codec.def +# End Source File +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\InBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\InBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\MSBFDecoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\OutBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "UnRar Sources" + +# PROP Default_Filter "" +# Begin Group "hpp" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Original\int64.hpp +# End Source File +# End Group +# Begin Source File + +SOURCE=Original\crc.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\errhnd.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\getbits.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\rar.hpp +# End Source File +# Begin Source File + +SOURCE=Original\rarvm.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\rdwrfn.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\rdwrfn.hpp +# End Source File +# Begin Source File + +SOURCE=Original\resource.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\smallfn.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\system.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\unpack.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=Original\unpack.hpp +# End Source File +# End Group +# Begin Group "Rar20" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Rar20\Rar20Const.h +# End Source File +# Begin Source File + +SOURCE=..\Rar20\Rar20Decoder.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\Rar20\Rar20Decoder.h +# End Source File +# Begin Source File + +SOURCE=..\Rar20\Rar20ExtConst.h +# End Source File +# Begin Source File + +SOURCE=..\Rar20\Rar20Multimedia.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\Rar20\Rar20Multimedia.h +# End Source File +# End Group +# Begin Group "LZ" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.cpp +# End Source File +# Begin Source File + +SOURCE=..\LZ\LZOutWindow.h +# End Source File +# End Group +# Begin Group "Huffman" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Huffman\HuffmanDecoder.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Rar29Decoder.cpp + +!IF "$(CFG)" == "Rar29 - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "Rar29 - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\Rar29Decoder.h +# End Source File +# End Target +# End Project diff --git a/7zip/Compress/Rar29/Rar29.dsw b/7zip/Compress/Rar29/Rar29.dsw new file mode 100755 index 00000000..61cbfecb --- /dev/null +++ b/7zip/Compress/Rar29/Rar29.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "RAR29"=.\RAR29.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/7zip/Compress/Rar29/Rar29Decoder.cpp b/7zip/Compress/Rar29/Rar29Decoder.cpp new file mode 100755 index 00000000..35daea87 --- /dev/null +++ b/7zip/Compress/Rar29/Rar29Decoder.cpp @@ -0,0 +1,153 @@ +// Rar29Decoder.cpp +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#include "StdAfx.h" + +#include "Rar29Decoder.h" + +#include "Windows/Defs.h" + +// #include "Original/unpack15.cpp" + +ErrorHandler ErrHandler; + +namespace NCompress { +namespace NRar29 { + +CDecoder::CDecoder(): + m_IsSolid(false), + // DataIO(NULL) + DataIO() +{ + Unp = new Unpack(&DataIO); + Unp->Init(NULL); +} + +CDecoder::~CDecoder() +{ + delete Unp; +} + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + // CCoderReleaser coderReleaser(this); + + DataIO.CurUnpRead=0; + DataIO.CurUnpWrite=0; + DataIO.UnpFileCRC=0xffffffff; + DataIO.PackedCRC=0xffffffff; + /* + DataIO.SetEncryption( + 0,0, + NULL,false); + */ + + DataIO.SetPackedSizeToRead(*inSize); + DataIO.SetFiles(inStream, outStream, progress); + DataIO.SetTestMode(false); + // DataIO.SetSkipUnpCRC(SkipSolid); + /* + if (!TestMode && Arc.NewLhd.FullUnpSize>0x1000) + CurFile.Prealloc(Arc.NewLhd.FullUnpSize); + + CurFile.SetAllowDelete(!Cmd->KeepBroken); + */ + + Unp->SetDestSize(*outSize); + + Unp->DoUnpack(29, m_IsSolid); + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CExitCode &exitCode) { return exitCode.Result; } + catch(...) { return S_FALSE; } +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +} + + +namespace NRar15 { + +CDecoder::CDecoder(): + m_IsSolid(false), + DataIO() +{ + Unp=new Unpack(&DataIO); + Unp->Init(NULL); +} + +CDecoder::~CDecoder() +{ + delete Unp; +} + + +STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + // CCoderReleaser coderReleaser(this); + + DataIO.CurUnpRead=0; + DataIO.CurUnpWrite=0; + DataIO.UnpFileCRC=0xffffffff; + DataIO.PackedCRC=0xffffffff; + /* + DataIO.SetEncryption( + 0,0, + NULL,false); + */ + + DataIO.SetPackedSizeToRead(*inSize); + DataIO.SetFiles(inStream, outStream, progress); + DataIO.SetTestMode(false); + // DataIO.SetSkipUnpCRC(SkipSolid); + /* + if (!TestMode && Arc.NewLhd.FullUnpSize>0x1000) + CurFile.Prealloc(Arc.NewLhd.FullUnpSize); + + CurFile.SetAllowDelete(!Cmd->KeepBroken); + */ + Unp->SetDestSize(*outSize); + Unp->DoUnpack(15, m_IsSolid); + return S_OK; +} + +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, + const UInt64 *outSize, + ICompressProgressInfo *progress) +{ + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } + catch(const CExitCode &exitCode) { return exitCode.Result; } + catch(...) { return S_FALSE;} +} + +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) +{ + if (size < 1) + return E_INVALIDARG; + m_IsSolid = (data[0] != 0); + return S_OK; +} + +} + +} diff --git a/7zip/Compress/Rar29/Rar29Decoder.h b/7zip/Compress/Rar29/Rar29Decoder.h new file mode 100755 index 00000000..de0044fd --- /dev/null +++ b/7zip/Compress/Rar29/Rar29Decoder.h @@ -0,0 +1,97 @@ +// Rar29Decoder.h +// According to unRAR license, +// this code may not be used to develop a +// RAR (WinRAR) compatible archiver + +#ifndef __RAR_DECODER_H +#define __RAR_DECODER_H + +#include "Common/MyCom.h" + +#include "../../ICoder.h" + +#include "Original/rar.hpp" + +namespace NCompress { + +namespace NRar29 { + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + Unpack *Unp; + bool m_IsSolid; +public: + ComprDataIO DataIO; + CDecoder(); + ~CDecoder(); + /* + class CCoderReleaser + { + CCoder *m_Coder; + public: + CCoderReleaser(CCoder *aCoder): m_Coder(aCoder) {} + ~CCoderReleaser() + { + m_Coder->DataIO.ReleaseStreams(); + } + }; + */ + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + // void ReleaseStreams(); + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +} + +namespace NRar15{ + +class CDecoder : + public ICompressCoder, + public ICompressSetDecoderProperties2, + public CMyUnknownImp +{ + Unpack *Unp; + bool m_IsSolid; +public: + ComprDataIO DataIO; + CDecoder(); + ~CDecoder(); + /* + class CCoderReleaser + { + CDecoder *m_Coder; + public: + CCoderReleaser(CDecoder *coder): m_Coder(coder) {} + ~CCoderReleaser() + { + m_Coder->DataIO.ReleaseStreams(); + } + }; + */ + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) + + // void ReleaseStreams(); + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); +}; + +} + +} + +#endif diff --git a/7zip/Compress/Rar29/StdAfx.cpp b/7zip/Compress/Rar29/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/7zip/Compress/Rar29/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/7zip/Compress/Rar29/StdAfx.h b/7zip/Compress/Rar29/StdAfx.h new file mode 100755 index 00000000..e7fb6986 --- /dev/null +++ b/7zip/Compress/Rar29/StdAfx.h @@ -0,0 +1,8 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" + +#endif diff --git a/7zip/Compress/Rar29/makefile b/7zip/Compress/Rar29/makefile new file mode 100755 index 00000000..19082cb9 --- /dev/null +++ b/7zip/Compress/Rar29/makefile @@ -0,0 +1,62 @@ +PROG = Rar29.dll +DEF_FILE = ../Codec.def +CFLAGS = $(CFLAGS) -I ../../../ +LIBS = $(LIBS) oleaut32.lib + +RAR29_OBJS = \ + $O\DllExports.obj \ + $O\Rar29Decoder.obj \ + +RAR29_OPT_OBJS = \ + $O\crc.obj \ + $O\errhnd.obj \ + $O\getbits.obj \ + $O\rarvm.obj \ + $O\rdwrfn.obj \ + $O\resource.obj \ + $O\smallfn.obj \ + $O\system.obj \ + $O\unpack.obj \ + +RAR20_OPT_OBJS = \ + $O\Rar20Decoder.obj \ + $O\Rar20Multimedia.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + +7ZIP_COMMON_OBJS = \ + $O\InBuffer.obj \ + $O\OutBuffer.obj \ + $O\StreamUtils.obj \ + +LZ_OBJS = \ + $O\LZOutWindow.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(RAR29_OBJS) \ + $(RAR29_OPT_OBJS) \ + $(RAR20_OPT_OBJS) \ + $(COMMON_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(LZ_OBJS) \ + $O\resource.res + +!include "../../../Build.mak" + +COMPL_SPEC = $(CPP) $(CFLAGS_O2) -DSILENT -DNOCRYPT -DNOVOLUME $** + +$(RAR29_OBJS): $(*B).cpp + $(COMPL) +$(RAR29_OPT_OBJS): Original/$(*B).cpp + $(COMPL_SPEC) +$(RAR20_OPT_OBJS): ../Rar20/$(*B).cpp + $(COMPL_O2) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(LZ_OBJS): ../LZ/$(*B).cpp + $(COMPL) diff --git a/7zip/Compress/Rar29/resource.rc b/7zip/Compress/Rar29/resource.rc new file mode 100755 index 00000000..bb5e2ec9 --- /dev/null +++ b/7zip/Compress/Rar29/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("Rar29 Codec", "Rar29") diff --git a/7zip/Crypto/7zAES/7zAES.cpp b/7zip/Crypto/7zAES/7zAES.cpp index dcf69cb6..a0d0882b 100755 --- a/7zip/Crypto/7zAES/7zAES.cpp +++ b/7zip/Crypto/7zAES/7zAES.cpp @@ -5,6 +5,7 @@ #include "Windows/Defs.h" #include "Windows/Synchronization.h" #include "../../Common/StreamObjects.h" +#include "../../Common/StreamUtils.h" #include "7zAES.h" // #include "../../Hash/Common/CryptoHashInterface.h" @@ -169,11 +170,11 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) RINOK(outStream->Write(&secondByte, 1, NULL)); if (_key.SaltSize > 0) { - RINOK(outStream->Write(_key.Salt, _key.SaltSize, NULL)); + RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL)); } if (ivSize > 0) { - RINOK(outStream->Write(_iv, ivSize, NULL)); + RINOK(WriteStream(outStream, _iv, ivSize, NULL)); } return S_OK; } diff --git a/7zip/Crypto/7zAES/7zAES.dsp b/7zip/Crypto/7zAES/7zAES.dsp index d329ea6f..1c177670 100755 --- a/7zip/Crypto/7zAES/7zAES.dsp +++ b/7zip/Crypto/7zAES/7zAES.dsp @@ -154,6 +154,14 @@ SOURCE=..\..\Common\StreamObjects.h # End Source File # Begin Source File +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File diff --git a/7zip/Crypto/7zAES/makefile b/7zip/Crypto/7zAES/makefile index 49b0fbf0..d8daaf69 100755 --- a/7zip/Crypto/7zAES/makefile +++ b/7zip/Crypto/7zAES/makefile @@ -22,6 +22,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\StreamObjects.obj \ + $O\StreamUtils.obj \ OBJS = \ $O\StdAfx.obj \ diff --git a/7zip/Crypto/RarAES/RarAES.cpp b/7zip/Crypto/RarAES/RarAES.cpp index 16a48349..00699158 100755 --- a/7zip/Crypto/RarAES/RarAES.cpp +++ b/7zip/Crypto/RarAES/RarAES.cpp @@ -17,7 +17,8 @@ namespace NRar29 { CDecoder::CDecoder(): _thereIsSalt(false), - _needCalculate(true) + _needCalculate(true), + _rar350Mode(false) { for (int i = 0; i < sizeof(_salt); i++) _salt[i] = 0; @@ -53,8 +54,12 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) return S_OK; } +static const int kMaxPasswordLength = 127 * 2; + STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) { + if (size > kMaxPasswordLength) + size = kMaxPasswordLength; bool same = false; if (size == buffer.GetCapacity()) { @@ -104,10 +109,9 @@ void CDecoder::Calculate() { if (_needCalculate) { - const int MAXPASSWORD = 128; - const int SALT_SIZE = 8; + const int kSaltSize = 8; - Byte rawPassword[2 * MAXPASSWORD+ SALT_SIZE]; + Byte rawPassword[kMaxPasswordLength + kSaltSize]; memcpy(rawPassword, buffer, buffer.GetCapacity()); @@ -115,24 +119,24 @@ void CDecoder::Calculate() if (_thereIsSalt) { - memcpy(rawPassword + rawLength, _salt, SALT_SIZE); - rawLength += SALT_SIZE; + memcpy(rawPassword + rawLength, _salt, kSaltSize); + rawLength += kSaltSize; } CSHA1 sha; sha.Init(); - + // seems rar reverts hash for sha. const int hashRounds = 0x40000; int i; for (i = 0; i < hashRounds; i++) { - sha.Update(rawPassword, rawLength); + sha.Update(rawPassword, rawLength, _rar350Mode); Byte pswNum[3]; pswNum[0] = (Byte)i; pswNum[1] = (Byte)(i >> 8); pswNum[2] = (Byte)(i >> 16); - sha.Update(pswNum, 3); + sha.Update(pswNum, 3, _rar350Mode); if (i % (hashRounds / 16) == 0) { CSHA1 shaTemp = sha; diff --git a/7zip/Crypto/RarAES/RarAES.h b/7zip/Crypto/RarAES/RarAES.h index 91473269..d86d0d17 100755 --- a/7zip/Crypto/RarAES/RarAES.h +++ b/7zip/Crypto/RarAES/RarAES.h @@ -30,6 +30,8 @@ class CDecoder: CCoderLibrary _aesLib; CMyComPtr<ICompressFilter> _aesFilter; + bool _rar350Mode; + void Calculate(); HRESULT CreateFilter(); @@ -48,6 +50,7 @@ public: STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); CDecoder(); + void SetRar350Mode(bool rar350Mode) { _rar350Mode = rar350Mode; } }; }} diff --git a/7zip/Crypto/RarAES/sha1.cpp b/7zip/Crypto/RarAES/sha1.cpp index d1a28ed4..4e76de9f 100755 --- a/7zip/Crypto/RarAES/sha1.cpp +++ b/7zip/Crypto/RarAES/sha1.cpp @@ -6,7 +6,7 @@ #include "sha1.h" -static inline rotlFixed(UInt32 x, int n) +static inline UInt32 rotlFixed(UInt32 x, int n) { return (x << n) | (x >> (32 - n)); } @@ -29,7 +29,7 @@ static inline rotlFixed(UInt32 x, int n) /* Hash a single 512-bit block. This is the core of the algorithm. */ -void CSHA1::Transform(const UInt32 data[16]) +void CSHA1::Transform(UInt32 data[16], bool returnRes) { UInt32 a, b, c, d, e; UInt32 W[16]; @@ -67,6 +67,9 @@ void CSHA1::Transform(const UInt32 data[16]) m_State[2] += c; m_State[3] += d; m_State[4] += e; + if (returnRes) + for (int i = 0 ; i < 16; i++) + data[i] = W[i]; /* Wipe variables */ a = b = c = d = e = 0; @@ -84,10 +87,11 @@ void CSHA1::Init() } -void CSHA1::WriteByteBlock() +void CSHA1::WriteByteBlock(bool returnRes) { UInt32 data32[16]; - for (int i = 0; i < 16; i++) + int i; + for (i = 0; i < 16; i++) { data32[i] = (UInt32(_buffer[i * 4 + 0]) << 24) + @@ -95,11 +99,21 @@ void CSHA1::WriteByteBlock() (UInt32(_buffer[i * 4 + 2]) << 8) + UInt32(_buffer[i * 4 + 3]); } - Transform(data32); + Transform(data32, returnRes); + if (returnRes) + for (i = 0; i < 16; i++) + { + UInt32 d = data32[i]; + _buffer[i * 4 + 0] = (Byte)(d >> 0); + _buffer[i * 4 + 1] = (Byte)(d >> 8); + _buffer[i * 4 + 2] = (Byte)(d >> 16); + _buffer[i * 4 + 3] = (Byte)(d >> 24); + } } -void CSHA1::Update(const Byte *data, size_t size) +void CSHA1::Update(Byte *data, size_t size, bool rar350Mode) { + bool returnRes = false; UInt32 curBufferPos = UInt32(m_Count) & 0x3F; while (size > 0) { @@ -112,7 +126,11 @@ void CSHA1::Update(const Byte *data, size_t size) if (curBufferPos == 64) { curBufferPos = 0; - WriteByteBlock(); + WriteByteBlock(returnRes); + if (returnRes) + for (int i = 0; i < 64; i++) + data[i - 64] = _buffer[i]; + returnRes = rar350Mode; } } } @@ -129,7 +147,8 @@ void CSHA1::Final(Byte *digest) WriteByteBlock(); _buffer[curBufferPos++] = 0; } - for (int i = 0; i < 8; i++) + int i; + for (i = 0; i < 8; i++) { _buffer[curBufferPos++] = Byte(lenInBits >> 56); lenInBits <<= 8; diff --git a/7zip/Crypto/RarAES/sha1.h b/7zip/Crypto/RarAES/sha1.h index 295f4131..a7cf9a16 100755 --- a/7zip/Crypto/RarAES/sha1.h +++ b/7zip/Crypto/RarAES/sha1.h @@ -10,17 +10,22 @@ #define HW 5 +// Sha1 implementation in RAR before version 3.60 has bug: +// it changes data bytes in some cases. +// So this class supports both versions: normal_SHA and rar3Mode + struct CSHA1 { UInt32 m_State[5]; UInt64 m_Count; unsigned char _buffer[64]; - void Transform(const UInt32 data[16]); - void WriteByteBlock(); + void Transform(UInt32 data[16], bool returnRes = false); + void WriteByteBlock(bool returnRes = false); +public: void Init(); - void Update(const Byte *data, size_t size); + void Update(Byte *data, size_t size, bool rar350Mode = false); void Final(Byte *digest); }; diff --git a/7zip/Crypto/Zip/ZipCipher.cpp b/7zip/Crypto/Zip/ZipCipher.cpp index 9098f6c9..47e2e712 100755 --- a/7zip/Crypto/Zip/ZipCipher.cpp +++ b/7zip/Crypto/Zip/ZipCipher.cpp @@ -5,6 +5,8 @@ #include "ZipCipher.h" #include "Windows/Defs.h" +#include "../../Common/StreamUtils.h" + namespace NCrypto { namespace NZip { @@ -56,7 +58,7 @@ HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) UInt32 processedSize; _cipher.EncryptHeader(header); - RINOK(outStream->Write(header, kHeaderSize, &processedSize)); + RINOK(WriteStream(outStream, header, kHeaderSize, &processedSize)); if (processedSize != kHeaderSize) return E_FAIL; return S_OK; @@ -81,7 +83,7 @@ HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) UInt64 nowPos = 0; Byte header[kHeaderSize]; UInt32 processedSize; - RINOK(inStream->Read(header, kHeaderSize, &processedSize)); + RINOK(ReadStream(inStream, header, kHeaderSize, &processedSize)); if (processedSize != kHeaderSize) return E_FAIL; _cipher.DecryptHeader(header); diff --git a/7zip/FileManager/App.cpp b/7zip/FileManager/App.cpp index ed78bb70..c85d4cef 100755 --- a/7zip/FileManager/App.cpp +++ b/7zip/FileManager/App.cpp @@ -340,7 +340,8 @@ void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2]) ReadToolbar(); ReloadRebar(hwnd); - for (int i = 0; i < kNumPanelsMax; i++) + int i; + for (i = 0; i < kNumPanelsMax; i++) PanelsCreated[i] = false; _window.Attach(hwnd); diff --git a/7zip/FileManager/App.h b/7zip/FileManager/App.h index 229c4806..45436ccb 100755 --- a/7zip/FileManager/App.h +++ b/7zip/FileManager/App.h @@ -200,8 +200,8 @@ public: { OnCopy(false, false, GetFocusedPanelIndex()); } void MoveTo() { OnCopy(true, false, GetFocusedPanelIndex()); } - void Delete() - { GetFocusedPanel().DeleteItems(); } + void Delete(bool toRecycleBin) + { GetFocusedPanel().DeleteItems(toRecycleBin); } void Split(); void Combine(); void Properties() diff --git a/7zip/FileManager/FSFolder.cpp b/7zip/FileManager/FSFolder.cpp index a6cf5701..e75a73a8 100755 --- a/7zip/FileManager/FSFolder.cpp +++ b/7zip/FileManager/FSFolder.cpp @@ -508,6 +508,40 @@ STDMETHODIMP CFSFolder::Delete(const UINT32 *indices, UINT32 numItems, return S_OK; } +/* +STDMETHODIMP CFSFolder::DeleteToRecycleBin(const UINT32 *indices, UINT32 numItems, + IProgress *progress) +{ + RINOK(progress->SetTotal(numItems)); + for (UINT32 i = 0; i < numItems; i++) + { + int index = indices[i]; + const CFileInfoW &fileInfo = _files[indices[i]]; + const UString fullPath = _path + fileInfo.Name; + CBuffer<TCHAR> buffer; + const CSysString fullPathSys = GetSystemString(fullPath); + buffer.SetCapacity(fullPathSys.Length() + 2); + memmove((TCHAR *)buffer, (const TCHAR *)fullPathSys, (fullPathSys.Length() + 1) * sizeof(TCHAR)); + ((TCHAR *)buffer)[fullPathSys.Length() + 1] = 0; + SHFILEOPSTRUCT fo; + fo.hwnd = 0; + fo.wFunc = FO_DELETE; + fo.pFrom = (const TCHAR *)buffer; + fo.pTo = 0; + fo.fFlags = FOF_ALLOWUNDO; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = 0; + fo.lpszProgressTitle = 0; + int res = SHFileOperation(&fo); + if (fo.fAnyOperationsAborted) + return E_ABORT; + UINT64 completed = i; + RINOK(progress->SetCompleted(&completed)); + } + return S_OK; +} +*/ + STDMETHODIMP CFSFolder::SetProperty(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) { diff --git a/7zip/FileManager/FSFolder.h b/7zip/FileManager/FSFolder.h index 08a987dc..3de312b1 100755 --- a/7zip/FileManager/FSFolder.h +++ b/7zip/FileManager/FSFolder.h @@ -28,6 +28,7 @@ class CFSFolder: public IFolderGetPath, public IFolderWasChanged, public IFolderOperations, + // public IFolderOperationsDeleteToRecycleBin, public IFolderGetItemFullSize, public IFolderClone, public IFolderGetSystemIconIndex, @@ -40,6 +41,7 @@ public: MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID) MY_QUERYINTERFACE_ENTRY(IFolderGetPath) MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) + // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin) MY_QUERYINTERFACE_ENTRY(IFolderOperations) MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize) MY_QUERYINTERFACE_ENTRY(IFolderClone) @@ -80,6 +82,8 @@ public: STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress); STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex); + // STDMETHOD(DeleteToRecycleBin)(const UINT32 *indices, UINT32 numItems, IProgress *progress); + private: UINT _fileCodePage; UString _path; diff --git a/7zip/FileManager/IFolder.h b/7zip/FileManager/IFolder.h index 10734f7b..8ab4d196 100755 --- a/7zip/FileManager/IFolder.h +++ b/7zip/FileManager/IFolder.h @@ -5,6 +5,15 @@ #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 @@ -16,85 +25,50 @@ namespace NPlugin }; } -// {23170F69-40C1-278A-0000-000800000000} -DEFINE_GUID(IID_IFolderFolder, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800000000") -IFolderFolder: public IUnknown -{ -public: - STDMETHOD(LoadItems)() = 0; - STDMETHOD(GetNumberOfItems)(UINT32 *numItems) = 0; - // STDMETHOD(GetNumberOfSubFolders)(UINT32 *numSubFolders) = 0; - STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) = 0; - STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder) = 0; - STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) = 0; - STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) = 0; - STDMETHOD(GetName)(BSTR *name) = 0; -}; - -// {23170F69-40C1-278A-0000-000800010000} -DEFINE_GUID(IID_IEnumProperties, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800010000") -IEnumProperties: public IUnknown -{ -public: - // STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator) = 0; - STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) = 0; +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) = 0; + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; }; -// {23170F69-40C1-278A-0000-000800020000} -DEFINE_GUID(IID_IFolderGetTypeID, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800020000") -IFolderGetTypeID: public IUnknown +FOLDER_INTERFACE(IFolderGetTypeID, 0x02) { -public: - STDMETHOD(GetTypeID)(BSTR *name) = 0; + STDMETHOD(GetTypeID)(BSTR *name) PURE; }; -// {23170F69-40C1-278A-0000-000800030000} -DEFINE_GUID(IID_IFolderGetPath, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800030000") -IFolderGetPath: public IUnknown +FOLDER_INTERFACE(IFolderGetPath, 0x03) { -public: - STDMETHOD(GetPath)(BSTR *path) = 0; + STDMETHOD(GetPath)(BSTR *path) PURE; }; -// {23170F69-40C1-278A-0000-000800040000} -DEFINE_GUID(IID_IFolderWasChanged, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800040000") -IFolderWasChanged: public IUnknown +FOLDER_INTERFACE(IFolderWasChanged, 0x04) { -public: - STDMETHOD(WasChanged)(INT32 *wasChanged) = 0; + STDMETHOD(WasChanged)(INT32 *wasChanged) PURE; }; /* -// {23170F69-40C1-278A-0000-000800050000} -DEFINE_GUID(IID_IFolderReload, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050000") -IFolderReload: public IUnknown +FOLDER_INTERFACE(IFolderReload, 0x05) { -public: - STDMETHOD(Reload)() = 0; + STDMETHOD(Reload)() PURE; }; */ -// {23170F69-40C1-278A-0000-000800060100} -DEFINE_GUID(IID_IFolderOperationsExtractCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x01, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060100") -IFolderOperationsExtractCallback: public IProgress +FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x06, 0x01) { -public: STDMETHOD(AskWrite)( const wchar_t *srcPath, INT32 srcIsFolder, @@ -102,19 +76,14 @@ public: const UINT64 *srcSize, const wchar_t *destPathRequest, BSTR *destPathResult, - INT32 *writeAnswer) = 0; - STDMETHOD(ShowMessage)(const wchar_t *message) = 0; - STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) = 0; + INT32 *writeAnswer) PURE; + STDMETHOD(ShowMessage)(const wchar_t *message) PURE; + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE; }; /* -// {23170F69-40C1-278A-0000-000800060200} -DEFINE_GUID(IID_IFolderOperationsUpdateCallback, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x02, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060200") -IFolderOperationsUpdateCallback: public IProgress +FOLDER_INTERFACE_SUB(IFolderOperationsUpdateCallback, IProgress, 0x06, 0x02) { -public: STDMETHOD(AskOverwrite)( const wchar_t *srcPath, INT32 destIsFolder, @@ -127,124 +96,88 @@ public: }; */ -// {23170F69-40C1-278A-0000-000800060000} -DEFINE_GUID(IID_IFolderOperations, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800060000") -IFolderOperations: public IUnknown -{ -public: - STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) = 0; - STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) = 0; - STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress) = 0; - STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress) = 0; +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) = 0; + const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE; STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems, - const wchar_t *path, IFolderOperationsExtractCallback *callback) = 0; + const wchar_t *path, IFolderOperationsExtractCallback *callback) PURE; STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, - const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress) = 0; - STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) = 0; + const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress) PURE; + STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) PURE; }; -// {23170F69-40C1-278A-0000-000800070000} -DEFINE_GUID(IID_IFolderGetSystemIconIndex, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800070000") -IFolderGetSystemIconIndex: public IUnknown +/* +FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03) { -public: - STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex) = 0; + STDMETHOD(DeleteToRecycleBin)(const UINT32 *indices, UINT32 numItems, IProgress *progress) PURE; }; +*/ -// {23170F69-40C1-278A-0000-000800080000} -DEFINE_GUID(IID_IFolderGetItemFullSize, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800080000") -IFolderGetItemFullSize: public IUnknown +FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07) { -public: - STDMETHOD(GetItemFullSize)(UINT32 index, PROPVARIANT *value, IProgress *progress) = 0; + STDMETHOD(GetSystemIconIndex)(UINT32 index, INT32 *iconIndex) PURE; }; -// {23170F69-40C1-278A-0000-000800090000} -DEFINE_GUID(IID_IFolderClone, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x09, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800090000") -IFolderClone: public IUnknown +FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08) { -public: - STDMETHOD(Clone)(IFolderFolder **resultFolder) = 0; + STDMETHOD(GetItemFullSize)(UINT32 index, PROPVARIANT *value, IProgress *progress) PURE; +}; + +FOLDER_INTERFACE(IFolderClone, 0x09) +{ + STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE; }; /* -// {23170F69-40C1-278A-0000-0008000A0000} -DEFINE_GUID(IID_IFolderOpen, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-0008000A0000") -IFolderOpen: public IUnknown +FOLDER_INTERFACE(IFolderOpen, 0x0A) { STDMETHOD(FolderOpen)( const wchar_t *aFileName, // IArchiveHandler100 **anArchiveHandler, // NZipRootRegistry::CArchiverInfo &anArchiverInfoResult, // UString &aDefaultName, - IOpenArchive2CallBack *anOpenArchive2CallBack) = 0; + IOpenArchive2CallBack *anOpenArchive2CallBack) PURE; }; */ -// {23170F69-40C1-278A-0000-000900000000} -DEFINE_GUID(IID_IFolderManager, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000900000000") -IFolderManager: public IUnknown +#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 + +FOLDER_MANAGER_INTERFACE(IFolderManager, 0x00) { - STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) = 0; - STDMETHOD(GetTypes)(BSTR *types); - STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension); - STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) = 0; + STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) PURE; + STDMETHOD(GetTypes)(BSTR *types) PURE; + STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension) PURE; + STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE; }; -// {23170F69-40C1-278A-0000-000900010000} -DEFINE_GUID(IID_IFolderManagerGetIconPath, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000900010000") -IFolderManagerGetIconPath: public IUnknown +FOLDER_MANAGER_INTERFACE(IFolderManagerGetIconPath, 0x01) { - STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) = 0; + STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath) PURE; }; /* -// {23170F69-40C1-278A-0000-000800050A00} -DEFINE_GUID(IID_IFolderExtract, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x0A, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050A00") -IFolderExtract: public IUnknown +FOLDER_INTERFACE(IFolderExtract, 0x05, 0x0A); { -public: - STDMETHOD(Clone)(IFolderFolder **aFolder) = 0; + STDMETHOD(Clone)(IFolderFolder **aFolder) PURE; }; -*/ -/* -// {23170F69-40C1-278A-0000-000800050400} -DEFINE_GUID(IID_IFolderChangeNotify, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x04, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050400") +FOLDER_INTERFACE(IFolderChangeNotify,0x05, 0x04, 0x00); IFolderChangeNotify: public IUnknown { -public: - STDMETHOD(OnChanged)() = 0; + STDMETHOD(OnChanged)() PURE; }; -// {23170F69-40C1-278A-0000-000800050500} -DEFINE_GUID(IID_IFolderSetChangeNotify, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x05, 0x05, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000800050500") -IFolderSetChangeNotify: public IUnknown +FOLDER_INTERFACE(IFolderSetChangeNotify, 0x05, 0x05); { -public: - STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) = 0; + STDMETHOD(SetChangeNotify)(IFolderChangeNotify *aChangeNotify) PURE; }; */ diff --git a/7zip/FileManager/MyLoadMenu.cpp b/7zip/FileManager/MyLoadMenu.cpp index 51b8fa56..9b684ec4 100755 --- a/7zip/FileManager/MyLoadMenu.cpp +++ b/7zip/FileManager/MyLoadMenu.cpp @@ -600,8 +600,11 @@ bool ExecuteFileCommand(int id) g_App.MoveTo(); break; case IDM_DELETE: - g_App.Delete(); + { + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + g_App.Delete(!shift); break; + } case IDM_FILE_SPLIT: g_App.Split(); break; diff --git a/7zip/FileManager/OptionsDialog.cpp b/7zip/FileManager/OptionsDialog.cpp index fc94a153..350d5263 100755 --- a/7zip/FileManager/OptionsDialog.cpp +++ b/7zip/FileManager/OptionsDialog.cpp @@ -94,7 +94,10 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance) if (::PropertySheet(&sheet) != -1) { if (langPage._langWasChanged) + { + g_App._window.SetText(LangLoadStringW(IDS_APP_TITLE, 0x03000000)); MyLoadMenu(); + } g_App.SetListSettings(); g_App.SetShowSystemMenu(); g_App.RefreshAllPanels(); diff --git a/7zip/FileManager/Panel.cpp b/7zip/FileManager/Panel.cpp index 8a06ac29..43905e0b 100755 --- a/7zip/FileManager/Panel.cpp +++ b/7zip/FileManager/Panel.cpp @@ -736,7 +736,7 @@ void CPanel::AddToArchive() names.Front(), (names.Size() > 1), false); CompressFiles(_currentFolderPrefix, archiveName, names, false, true, false); - KillSelection(); + // KillSelection(); } void CPanel::ExtractArchives() diff --git a/7zip/FileManager/Panel.h b/7zip/FileManager/Panel.h index fc0a9c68..95ab0d3c 100755 --- a/7zip/FileManager/Panel.h +++ b/7zip/FileManager/Panel.h @@ -136,8 +136,9 @@ struct CSelectedState { int FocusedItem; UString FocusedName; + bool SelectFocused; UStringVector SelectedNames; - CSelectedState(): FocusedItem(-1) {} + CSelectedState(): FocusedItem(-1), SelectFocused(false) {} }; class CPanel:public NWindows::NControl::CWindow2 @@ -173,7 +174,7 @@ class CPanel:public NWindows::NControl::CWindow2 public: CPanelCallback *_panelCallback; - void DeleteItems(); + void DeleteItems(bool toRecycleBin); void CreateFolder(); void CreateFile(); @@ -185,8 +186,8 @@ private: // void InitColumns2(PROPID sortID); void InsertColumn(int index); - void SetFocusedSelectedItem(int index); - void RefreshListCtrl(const UString &focusedName, int focusedPos, + void SetFocusedSelectedItem(int index, bool select); + void RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, const UStringVector &selectedNames); void OnShiftSelectMessage(); @@ -224,6 +225,7 @@ public: bool _showRealFileIcons; // bool _virtualMode; // CUIntVector _realIndices; + bool _enableItemChangeNotify; bool _mySelectMode; CBoolVector _selectedStatusVector; @@ -312,7 +314,8 @@ public: _selectionIsDefined(false), _ListViewMode(3), _xSize(300), - _mySelectMode(false) + _mySelectMode(false), + _enableItemChangeNotify(true) {} void SetExtendedStyle() diff --git a/7zip/FileManager/PanelFolderChange.cpp b/7zip/FileManager/PanelFolderChange.cpp index c38989f7..e632c5f7 100755 --- a/7zip/FileManager/PanelFolderChange.cpp +++ b/7zip/FileManager/PanelFolderChange.cpp @@ -95,7 +95,7 @@ HRESULT CPanel::BindToPathAndRefresh(const UString &path) { CDisableTimerProcessing disableTimerProcessing1(*this); RINOK(BindToPath(path)); - RefreshListCtrl(UString(), -1, UStringVector()); + RefreshListCtrl(UString(), -1, true, UStringVector()); return S_OK; } @@ -112,7 +112,7 @@ void CPanel::OpenBookmark(int index) UString GetFolderPath(IFolderFolder * folder) { CMyComPtr<IFolderGetPath> folderGetPath; - if (folder->QueryInterface(&folderGetPath) == S_OK) + if (folder->QueryInterface(IID_IFolderGetPath, (void **)&folderGetPath) == S_OK) { CMyComBSTR path; if (folderGetPath->GetPath(&path) == S_OK) @@ -310,7 +310,7 @@ void CPanel::OpenParentFolder() */ LoadFullPath(); ::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix)); - RefreshListCtrl(focucedName, -1, selectedItems); + RefreshListCtrl(focucedName, -1, true, selectedItems); _listView.EnsureVisible(_listView.GetFocusedItem(), false); RefreshStatusBar(); } @@ -336,7 +336,7 @@ void CPanel::OpenRootFolder() CDisableTimerProcessing disableTimerProcessing1(*this); _parentFolders.Clear(); SetToRootFolder(); - RefreshListCtrl(UString(), 0, UStringVector()); + RefreshListCtrl(UString(), -1, true, UStringVector()); // ::SetCurrentDirectory(::GetSystemString(_currentFolderPrefix)); /* BeforeChangeFolder(); diff --git a/7zip/FileManager/PanelItems.cpp b/7zip/FileManager/PanelItems.cpp index d400015b..b839cc8f 100755 --- a/7zip/FileManager/PanelItems.cpp +++ b/7zip/FileManager/PanelItems.cpp @@ -12,10 +12,12 @@ #include "../PropID.h" #include "Panel.h" +#include "resource.h" #include "RootFolder.h" #include "PropertyName.h" +#include "LangUtils.h" using namespace NWindows; @@ -201,7 +203,7 @@ void CPanel::InsertColumn(int index) void CPanel::RefreshListCtrl() { - RefreshListCtrl(UString(), 0, UStringVector()); + RefreshListCtrl(UString(), -1, true, UStringVector()); } int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); @@ -245,35 +247,42 @@ void CPanel::SaveSelectedState(CSelectedState &s) s.FocusedName.Empty(); s.SelectedNames.Clear(); s.FocusedItem = _listView.GetFocusedItem(); - if (s.FocusedItem >= 0) - { - int realIndex = GetRealItemIndex(s.FocusedItem); - if (realIndex != kParentIndex) - s.FocusedName = GetItemName(realIndex); - /* - const int kSize = 1024; - TCHAR name[kSize + 1]; - LVITEM item; - item.iItem = focusedItem; - item.pszText = name; - item.cchTextMax = kSize; - item.iSubItem = 0; - item.mask = LVIF_TEXT; - if (_listView.GetItem(&item)) - focusedName = GetUnicodeString(item.pszText); - */ - } if (!_focusedName.IsEmpty()) { s.FocusedName = _focusedName; + s.SelectFocused = true; _focusedName.Empty(); } + else + { + if (s.FocusedItem >= 0) + { + int realIndex = GetRealItemIndex(s.FocusedItem); + if (realIndex != kParentIndex) + s.FocusedName = GetItemName(realIndex); + /* + const int kSize = 1024; + TCHAR name[kSize + 1]; + LVITEM item; + item.iItem = focusedItem; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT; + if (_listView.GetItem(&item)) + focusedName = GetUnicodeString(item.pszText); + */ + } + } GetSelectedNames(s.SelectedNames); } void CPanel::RefreshListCtrl(const CSelectedState &s) { - RefreshListCtrl(s.FocusedName, s.FocusedItem, s.SelectedNames); + bool selectFocused = s.SelectFocused; + if (_mySelectMode) + selectFocused = true; + RefreshListCtrl(s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames); } void CPanel::RefreshListCtrlSaveFocused() @@ -283,11 +292,13 @@ void CPanel::RefreshListCtrlSaveFocused() RefreshListCtrl(state); } -void CPanel::SetFocusedSelectedItem(int index) +void CPanel::SetFocusedSelectedItem(int index, bool select) { - UINT state = LVIS_FOCUSED | LVIS_SELECTED; + UINT state = LVIS_FOCUSED; + if (select) + state |= LVIS_SELECTED; _listView.SetItemState(index, state, state); - if (!_mySelectMode) + if (!_mySelectMode && select) { int realIndex = GetRealItemIndex(index); if (realIndex != kParentIndex) @@ -295,7 +306,7 @@ void CPanel::SetFocusedSelectedItem(int index) } } -void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, +void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, const UStringVector &selectedNames) { LoadFullPathAndShow(); @@ -468,13 +479,13 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, // OutputDebugStringA("End2\n"); if(_listView.GetItemCount() > 0 && cursorIndex >= 0) - SetFocusedSelectedItem(cursorIndex); + SetFocusedSelectedItem(cursorIndex, selectFocused); _listView.SortItems(CompareItems, (LPARAM)this); if (cursorIndex < 0 && _listView.GetItemCount() > 0) { if (focusedPos >= _listView.GetItemCount()) focusedPos = _listView.GetItemCount() - 1; - SetFocusedSelectedItem(focusedPos); + SetFocusedSelectedItem(focusedPos, true); } // m_RedrawEnabled = true; _listView.EnsureVisible(_listView.GetFocusedItem(), false); @@ -514,9 +525,12 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UINT32> &indices) const int focusedItem = _listView.GetFocusedItem(); if (focusedItem >= 0) { - int realIndex = GetRealItemIndex(focusedItem); - if (realIndex != kParentIndex) + if(_listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) indices.Add(realIndex); + } } } @@ -571,7 +585,7 @@ void CPanel::OpenSelectedItems(bool tryInternal) GetOperatedItemIndices(indices); if (indices.Size() > 20) { - MessageBox(L"Too much items"); + MessageBox(LangLoadStringW(IDS_TOO_MANY_ITEMS, 0x02000606)); return; } @@ -659,7 +673,8 @@ void CPanel::ReadListViewInfo() void CPanel::SaveListViewInfo() { - for(int i = 0; i < _visibleProperties.Size(); i++) + int i; + for(i = 0; i < _visibleProperties.Size(); i++) { CItemProperty &property = _visibleProperties[i]; LVCOLUMN winColumnInfo; diff --git a/7zip/FileManager/PanelKey.cpp b/7zip/FileManager/PanelKey.cpp index d14c024a..f623332a 100755 --- a/7zip/FileManager/PanelKey.cpp +++ b/7zip/FileManager/PanelKey.cpp @@ -152,8 +152,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) */ case VK_DELETE: { - // if (shift) - DeleteItems(); + DeleteItems(!shift); return true; } case VK_INSERT: diff --git a/7zip/FileManager/PanelListNotify.cpp b/7zip/FileManager/PanelListNotify.cpp index ec88abc5..ac8c069d 100755 --- a/7zip/FileManager/PanelListNotify.cpp +++ b/7zip/FileManager/PanelListNotify.cpp @@ -169,9 +169,12 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) { case LVN_ITEMCHANGED: { - if (!_mySelectMode) - OnItemChanged((LPNMLISTVIEW)header); - RefreshStatusBar(); + if (_enableItemChangeNotify) + { + if (!_mySelectMode) + OnItemChanged((LPNMLISTVIEW)header); + RefreshStatusBar(); + } return false; } /* @@ -257,6 +260,8 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) */ case NM_CLICK: { + // we need SetFocusToList, if we drag-select items from other panel. + SetFocusToList(); RefreshStatusBar(); if(_mySelectMode) if(g_ComCtl32Version >= MAKELONG(71, 4)) diff --git a/7zip/FileManager/PanelMenu.cpp b/7zip/FileManager/PanelMenu.cpp index 091f0317..f10fa1aa 100755 --- a/7zip/FileManager/PanelMenu.cpp +++ b/7zip/FileManager/PanelMenu.cpp @@ -261,7 +261,8 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec, return; UString currentFolderUnicode = _currentFolderPrefix; UStringVector names; - for(int i = 0; i < operatedIndices.Size(); i++) + int i; + for(i = 0; i < operatedIndices.Size(); i++) names.Add(currentFolderUnicode + GetItemName(operatedIndices[i])); CRecordVector<const wchar_t *> namePointers; for(i = 0; i < operatedIndices.Size(); i++) diff --git a/7zip/FileManager/PanelOperations.cpp b/7zip/FileManager/PanelOperations.cpp index 5e23cbcb..5efbc2d7 100755 --- a/7zip/FileManager/PanelOperations.cpp +++ b/7zip/FileManager/PanelOperations.cpp @@ -7,6 +7,7 @@ #include "Panel.h" #include "Common/StringConvert.h" +#include "Common/DynamicBuffer.h" #include "Windows/FileDir.h" #include "Windows/ResourceString.h" #include "Windows/Thread.h" @@ -35,8 +36,7 @@ struct CThreadDelete { NCOM::CComInitializer comInitializer; UpdateCallbackSpec->ProgressDialog.WaitCreating(); - Result = FolderOperations->Delete(&Indices.Front(), - Indices.Size(), UpdateCallback); + Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback); UpdateCallbackSpec->ProgressDialog.MyClose(); return 0; } @@ -47,15 +47,8 @@ struct CThreadDelete } }; -void CPanel::DeleteItems() +void CPanel::DeleteItems(bool toRecycleBin) { - CMyComPtr<IFolderOperations> folderOperations; - if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) - { - MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); - return; - } - CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); CRecordVector<UInt32> indices; GetOperatedItemIndices(indices); @@ -63,6 +56,55 @@ void CPanel::DeleteItems() return; CSelectedState state; SaveSelectedState(state); + if (IsFSFolder()) + { + CDynamicBuffer<TCHAR> buffer; + size_t size = 0; + for (int i = 0; i < indices.Size(); i++) + { + const CSysString path = GetSystemString(GetFsPath() + GetItemName(indices[i])); + buffer.EnsureCapacity(size + path.Length() + 1); + memmove(((TCHAR *)buffer) + size, (const TCHAR *)path, (path.Length() + 1) * sizeof(TCHAR)); + size += path.Length() + 1; + } + buffer.EnsureCapacity(size + 1); + ((TCHAR *)buffer)[size] = 0; + SHFILEOPSTRUCT fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const TCHAR *)buffer; + fo.pTo = 0; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + // fo.fFlags |= FOF_NOCONFIRMATION; + // fo.fFlags |= FOF_NOERRORUI; + // fo.fFlags |= FOF_SILENT; + // fo.fFlags |= FOF_WANTNUKEWARNING; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = 0; + fo.lpszProgressTitle = 0; + int res = SHFileOperation(&fo); + /* + if (fo.fAnyOperationsAborted) + { + MessageBoxError(result, LangLoadStringW(IDS_ERROR_DELETING, 0x03020217)); + } + */ + /* + (!result) + return GetLastError(); + */ + } + else + { + + CMyComPtr<IFolderOperations> folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } UString title; UString message; @@ -112,6 +154,7 @@ void CPanel::DeleteItems() HRESULT result = deleter.Result; if (result != S_OK) MessageBoxError(result, LangLoadStringW(IDS_ERROR_DELETING, 0x03020217)); + } RefreshListCtrl(state); } @@ -152,6 +195,11 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFO * lpnmh) // Can't use RefreshListCtrl here. // RefreshListCtrlSaveFocused(); _focusedName = newName; + + // We need clear all items to disable GetText before Reload: + // number of items can change. + _listView.DeleteAllItems(); + PostMessage(kReLoadMessage); return TRUE; } @@ -186,6 +234,7 @@ void CPanel::CreateFolder() if (!_mySelectMode) state.SelectedNames.Clear(); state.FocusedName = newName; + state.SelectFocused = true; RefreshListCtrl(state); } @@ -219,6 +268,7 @@ void CPanel::CreateFile() if (!_mySelectMode) state.SelectedNames.Clear(); state.FocusedName = newName; + state.SelectFocused = true; RefreshListCtrl(state); } diff --git a/7zip/FileManager/PanelSelect.cpp b/7zip/FileManager/PanelSelect.cpp index 595a19e4..cbbc13b6 100755 --- a/7zip/FileManager/PanelSelect.cpp +++ b/7zip/FileManager/PanelSelect.cpp @@ -129,6 +129,8 @@ void CPanel::UpdateSelection() { if (!_mySelectMode) { + bool enableTemp = _enableItemChangeNotify; + _enableItemChangeNotify = false; int numItems = _listView.GetItemCount(); for (int i = 0; i < numItems; i++) { @@ -140,6 +142,7 @@ void CPanel::UpdateSelection() _listView.SetItemState(i, value, LVIS_SELECTED); } } + _enableItemChangeNotify = enableTemp; } _listView.RedrawAllItems(); } @@ -213,6 +216,24 @@ void CPanel::SelectAll(bool selectMode) void CPanel::InvertSelection() { + if (!_mySelectMode) + { + int numSelected = 0; + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (_selectedStatusVector[i]) + numSelected++; + if (numSelected == 1) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + { + int realIndex = GetRealItemIndex(focused); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + _selectedStatusVector[realIndex] = false; + } + } + } for (int i = 0; i < _selectedStatusVector.Size(); i++) _selectedStatusVector[i] = !_selectedStatusVector[i]; UpdateSelection(); diff --git a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp index dc050d11..8ea16ea8 100755 --- a/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp +++ b/7zip/FileManager/Resource/BenchmarkDialog/BenchmarkDialog.cpp @@ -499,7 +499,6 @@ public: Pos = 0; } STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize) @@ -517,11 +516,6 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed return S_OK; } -STDMETHODIMP CBenchmarkInStream::ReadPart(void *data, UInt32 size, UInt32 *processedSize) -{ - return Read(data, size, processedSize); -} - class CBenchmarkOutStream: public ISequentialOutStream, public CMyUnknownImp @@ -542,7 +536,6 @@ public: } MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) @@ -560,11 +553,6 @@ STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *p return S_OK; } -STDMETHODIMP CBenchmarkOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - class CCompareOutStream: public ISequentialOutStream, public CMyUnknownImp @@ -574,7 +562,6 @@ public: MY_UNKNOWN_IMP void Init() { CRC.Init(); } STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); }; STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) @@ -585,11 +572,6 @@ STDMETHODIMP CCompareOutStream::Write(const void *data, UInt32 size, UInt32 *pro return S_OK; } -STDMETHODIMP CCompareOutStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID, const GUID *interfaceID, void **outObject); diff --git a/7zip/FileManager/StringUtils.cpp b/7zip/FileManager/StringUtils.cpp index 93fbe094..47560b05 100755 --- a/7zip/FileManager/StringUtils.cpp +++ b/7zip/FileManager/StringUtils.cpp @@ -9,7 +9,8 @@ void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) dest1.Empty(); dest2.Empty(); bool quoteMode = false; - for (int i = 0; i < src.Length(); i++) + int i; + for (i = 0; i < src.Length(); i++) { wchar_t c = src[i]; if (c == L'\"') diff --git a/7zip/FileManager/TextPairs.cpp b/7zip/FileManager/TextPairs.cpp index 6ccc6bf7..b32d02cf 100755 --- a/7zip/FileManager/TextPairs.cpp +++ b/7zip/FileManager/TextPairs.cpp @@ -119,19 +119,15 @@ static int ComparePairIDs(const UString &s1, const UString &s2) { return s1.CollateNoCase(s2); } static int ComparePairItems(const CTextPair &p1, const CTextPair &p2) { return ComparePairIDs(p1.ID, p2.ID); } -static int __cdecl ComparePairItems(const void *a1, const void *a2) -{ - return ComparePairItems( - *(*((const CTextPair **)a1)), - *(*((const CTextPair **)a2))); -} + +// typedef void* MY_PVOID; + +// static int ComparePairItems(const MY_PVOID *a1, const MY_PVOID *a2, void *param) +static int ComparePairItems(void *const *a1, void *const *a2, void *param) + { return ComparePairItems(**(const CTextPair **)a1, **(const CTextPair **)a2); } void CPairsStorage::Sort() -{ - CPointerVector &pointerVector = Pairs; - qsort(&pointerVector[0], Pairs.Size(), sizeof(void *), - ComparePairItems); -} + { Pairs.Sort(ComparePairItems, 0); } int CPairsStorage::FindID(const UString &id, int &insertPos) { diff --git a/7zip/FileManager/resource.h b/7zip/FileManager/resource.h index 2f76f1e4..d7063043 100755 --- a/7zip/FileManager/resource.h +++ b/7zip/FileManager/resource.h @@ -105,6 +105,7 @@ #define IDS_SELECT_MASK 2252 #define IDS_FOLDERS_HISTORY 2260 #define IDS_N_SELECTED_ITEMS 2270 +#define IDS_TOO_MANY_ITEMS 2279 #define IDS_WANT_UPDATE_MODIFIED_FILE 2280 #define IDS_CANNOT_UPDATE_FILE 2281 #define IDS_CANNOT_START_EDITOR 2282 diff --git a/7zip/FileManager/resource.rc b/7zip/FileManager/resource.rc index 1f8946e3..8e92d804 100755 --- a/7zip/FileManager/resource.rc +++ b/7zip/FileManager/resource.rc @@ -176,6 +176,7 @@ BEGIN IDS_COMMENT "Comment" IDS_COMMENT2 "&Comment:" IDS_SYSTEM "System" + IDS_TOO_MANY_ITEMS "Too many items" IDS_WANT_UPDATE_MODIFIED_FILE "File '{0}' was modified.\nDo you want to update it in the archive?" IDS_CANNOT_UPDATE_FILE "Can not update file\n'{0}'" IDS_CANNOT_START_EDITOR "Cannot start editor." diff --git a/7zip/Guid.txt b/7zip/Guid.txt new file mode 100755 index 00000000..66d202e1 --- /dev/null +++ b/7zip/Guid.txt @@ -0,0 +1,152 @@ +{23170F69-40C1-278A-0000-} + +000000xx0000 IProgress.h + +05 IProgress + + +000300xx0000 IStream.h + +01 ISequentialInStream +02 ISequentialOutStream +03 IInStream +04 IOutStream +06 IStreamGetSize +07 IOutStreamFlush + + +000400xx0000 ICoder.h + +04 ICompressProgressInfo +05 ICompressCoder +18 ICompressCoder2 +20 ICompressSetCoderProperties +21 ICompressSetDecoderProperties // +22 ICompressSetDecoderProperties2 +23 ICompressWriteCoderProperties +24 ICompressGetInStreamProcessedSize +30 ICompressGetSubStreamSize +31 ICompressSetInStream +32 ICompressSetOutStream +33 ICompressSetInStreamSize +34 ICompressSetOutStreamSize +40 ICompressFilter +80 ICryptoProperties +90 ICryptoSetPassword +A0 ICryptoSetCRC + + +000500xx0000 IPassword.h + +10 ICryptoGetTextPassword +11 ICryptoGetTextPassword2 + + +000600xx0000 IArchive.h + +03 ISetProperties + +10 IArchiveOpenCallback +20 IArchiveExtractCallback +30 IArchiveOpenVolumeCallback +40 IInArchiveGetStream +50 IArchiveOpenSetSubArchiveName +60 IInArchive + +80 IArchiveUpdateCallback +82 IArchiveUpdateCallback2 +A0 IOutArchive + + +000100050001 Agent.h::IArchiveFolderInternal + + +000100xx0000 IFolderArchive.h + +05 IArchiveFolder +06 IInFolderArchive +07 IFileExtractCallback.h::IFolderArchiveExtractCallback +0A IOutFolderArchive +0B IFolderArchiveUpdateCallback + + + + +000800xxyy00 FolderInterface.h:: + +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 IFolderOpen // + +000900000000} FolderInterface.h::IFolderManager +000900010000} FolderInterface.h::IFolderManagerGetIconPath + + +{23170F69-40C1-278D-0000-000100010000} PluginInterface::IInitContextMenu +{23170F69-40C1-278D-0000-000100020100} PluginInterface::IPluginOptionsCallback +{23170F69-40C1-278D-0000-000100020000} PluginInterface::IPluginOptions + + +Handler GUIDs: + +{23170F69-40C1-278A-1000-000110xx0000} + +01 Zip +02 BZip2 +03 Rar +04 Arj +05 Z +06 Lzh +07 7z +08 Cab + +E9 Chm +EA Split +EB Rpm +EC Deb +ED Cpio +EE Tar +EF GZip + +{23170F69-40C1-278A-1000-000100030000} CAgentArchiveHandle +{23170F69-40C1-278A-1000-000100020000} ContextMenu.h::CZipContextMenu + +{23170F69-40C1-278B- + +0000-000000000000} Copy +0203-020000000000} Swap2 +0203-040000000000} Swap4 +0301-01000000ee00} LZMA +0303-xxdd0000ee00} Branch +0304-01000000ee00} PPMD +0401-01000000ee00} Shrink +0401-06000000ee00} Implode +0401-08000000ee00} Deflate +0401-09000000ee00} Deflate64 +0402-02000000ee00} Bzip2 +0402-050000000000} Z +0403-010000000000} Rar15 +0403-020000000000} Rar20 +0403-030000000000} Rar29 +0601-01000000ee00} AES128_CBC +0601-81000000ee00} AES256_CBC +06F1-070100000000} 7zAES + + + +{23170F69-40C1-278D-1000-000100020000} OptionsDialog.h::CLSID_CSevenZipOptions + diff --git a/7zip/ICoder.h b/7zip/ICoder.h index 631df96c..8d556fdc 100755 --- a/7zip/ICoder.h +++ b/7zip/ICoder.h @@ -5,33 +5,27 @@ #include "IStream.h" -// {23170F69-40C1-278A-0000-000200040000} -DEFINE_GUID(IID_ICompressProgressInfo, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200040000") -ICompressProgressInfo: public IUnknown +// "23170F69-40C1-278A-0000-000400xx0000" +#define CODER_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown + +CODER_INTERFACE(ICompressProgressInfo, 0x04) { - STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) = 0; + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE; }; -// {23170F69-40C1-278A-0000-000200050000} -DEFINE_GUID(IID_ICompressCoder, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200050000") -ICompressCoder: public IUnknown +CODER_INTERFACE(ICompressCoder, 0x05) { STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) = 0; + ICompressProgressInfo *progress) PURE; }; -// {23170F69-40C1-278A-0000-000200180000} -DEFINE_GUID(IID_ICompressCoder2, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200180000") -ICompressCoder2: public IUnknown +CODER_INTERFACE(ICompressCoder2, 0x18) { STDMETHOD(Code)(ISequentialInStream **inStreams, const UInt64 **inSizes, @@ -61,106 +55,62 @@ namespace NCoderPropID }; } -// {23170F69-40C1-278A-0000-000200200000} -DEFINE_GUID(IID_ICompressSetCoderProperties, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200200000") -ICompressSetCoderProperties: public IUnknown +CODER_INTERFACE(ICompressSetCoderProperties, 0x20) { STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *properties, UInt32 numProperties) PURE; }; /* -// {23170F69-40C1-278A-0000-000200210000} -DEFINE_GUID(IID_ICompressSetDecoderProperties, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210000") -ICompressSetDecoderProperties: public IUnknown +CODER_INTERFACE(ICompressSetCoderProperties, 0x21) { STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE; }; */ -// {23170F69-40C1-278A-0000-000200210200} -DEFINE_GUID(IID_ICompressSetDecoderProperties2, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, 0x02, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200210200") -ICompressSetDecoderProperties2: public IUnknown +CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22) { STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE; }; -// {23170F69-40C1-278A-0000-000200230000} -DEFINE_GUID(IID_ICompressWriteCoderProperties, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200230000") -ICompressWriteCoderProperties: public IUnknown +CODER_INTERFACE(ICompressWriteCoderProperties, 0x23) { STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE; }; -// {23170F69-40C1-278A-0000-000200240000} -DEFINE_GUID(IID_ICompressGetInStreamProcessedSize, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200240000") -ICompressGetInStreamProcessedSize: public IUnknown +CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24) { STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE; }; -// {23170F69-40C1-278A-0000-000200250000} -DEFINE_GUID(IID_ICompressGetSubStreamSize, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000") -ICompressGetSubStreamSize: public IUnknown +CODER_INTERFACE(ICompressGetSubStreamSize, 0x30) { STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE; }; -// {23170F69-40C1-278A-0000-000200260000} -DEFINE_GUID(IID_ICompressSetInStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200260000") -ICompressSetInStream: public IUnknown +CODER_INTERFACE(ICompressSetInStream, 0x31) { STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE; STDMETHOD(ReleaseInStream)() PURE; }; -// {23170F69-40C1-278A-0000-000200270000} -DEFINE_GUID(IID_ICompressSetOutStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000") -ICompressSetOutStream: public IUnknown +CODER_INTERFACE(ICompressSetOutStream, 0x32) { STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE; STDMETHOD(ReleaseOutStream)() PURE; }; -// {23170F69-40C1-278A-0000-000200280000} -DEFINE_GUID(IID_ICompressSetInStreamSize, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200280000") -ICompressSetInStreamSize: public IUnknown +CODER_INTERFACE(ICompressSetInStreamSize, 0x33) { STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE; }; -// {23170F69-40C1-278A-0000-000200290000} -DEFINE_GUID(IID_ICompressSetOutStreamSize, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200290000") -ICompressSetOutStreamSize: public IUnknown +CODER_INTERFACE(ICompressSetOutStreamSize, 0x34) { STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE; }; -// {23170F69-40C1-278A-0000-000200400000} -DEFINE_GUID(IID_ICompressFilter, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200400000") -ICompressFilter: public IUnknown +CODER_INTERFACE(ICompressFilter, 0x40) { STDMETHOD(Init)() PURE; STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE; @@ -171,16 +121,22 @@ ICompressFilter: public IUnknown // (it's for crypto block algorithms). }; -// {23170F69-40C1-278A-0000-000200800000} -DEFINE_GUID(IID_ICryptoProperties, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200800000") -ICryptoProperties: public IUnknown +CODER_INTERFACE(ICryptoProperties, 0x80) { STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE; STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE; }; +CODER_INTERFACE(ICryptoSetPassword, 0x90) +{ + STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; +}; + +CODER_INTERFACE(ICryptoSetCRC, 0xA0) +{ + STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; +}; + ////////////////////// // It's for DLL file namespace NMethodPropID diff --git a/7zip/IPassword.h b/7zip/IPassword.h index a302b26c..8f2adcca 100755 --- a/7zip/IPassword.h +++ b/7zip/IPassword.h @@ -6,38 +6,18 @@ #include "../Common/MyUnknown.h" #include "../Common/Types.h" -// {23170F69-40C1-278A-0000-000200250000} -DEFINE_GUID(IID_ICryptoSetPassword, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200250000") -ICryptoSetPassword: public IUnknown -{ - STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE; -}; - -// {23170F69-40C1-278A-0000-000200251000} -DEFINE_GUID(IID_ICryptoSetCRC, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, 0x10, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200251000") -ICryptoSetCRC: public IUnknown -{ - STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE; -}; +// MIDL_INTERFACE("23170F69-40C1-278A-0000-000500xx0000") +#define PASSWORD_INTERFACE(i, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x05, 0x00, x, 0x00, 0x00); \ +struct i: public IUnknown -// {23170F69-40C1-278A-0000-000200270000} -DEFINE_GUID(IID_ICryptoGetTextPassword, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270000") -ICryptoGetTextPassword: public IUnknown +PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10) { STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE; }; -// {23170F69-40C1-278A-0000-000200270200} -DEFINE_GUID(IID_ICryptoGetTextPassword2, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x02, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000200270200") -ICryptoGetTextPassword2: public IUnknown +PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11) { STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE; }; diff --git a/7zip/IProgress.h b/7zip/IProgress.h index 23edfc73..aa3b64cc 100755 --- a/7zip/IProgress.h +++ b/7zip/IProgress.h @@ -12,7 +12,6 @@ DEFINE_GUID(IID_IProgress, MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050000") IProgress: public IUnknown { -public: STDMETHOD(SetTotal)(UInt64 total) PURE; STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE; }; diff --git a/7zip/IStream.h b/7zip/IStream.h index fd98f771..bba21a31 100755 --- a/7zip/IStream.h +++ b/7zip/IStream.h @@ -1,79 +1,62 @@ // IStream.h -#ifndef __ISTREAMS_H -#define __ISTREAMS_H +#ifndef __ISTREAM_H +#define __ISTREAM_H #include "../Common/MyUnknown.h" #include "../Common/Types.h" -// {23170F69-40C1-278A-0000-000000010000} -DEFINE_GUID(IID_ISequentialInStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000000010000") -ISequentialInStream : public IUnknown +// "23170F69-40C1-278A-0000-000300xx0000" + +#define STREAM_INTERFACE_SUB(i, b, x) \ +DEFINE_GUID(IID_ ## i, \ +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \ +struct i: public b + +#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x) + +STREAM_INTERFACE(ISequentialInStream, 0x01) { -public: - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0; - STDMETHOD(ReadPart)(void *data, UInt32 size, UInt32 *processedSize) = 0; - - // For both functions Out: if (*processedSize == 0) then - // there are no more bytes in stream. - // Read function always tries to read "size" bytes from stream. It - // can read less only if it reaches end of stream. - // ReadPart function can read X bytes: (0<=X<="size") and X can - // be less than number of remaining bytes in stream. + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + Out: if size != 0, return_value = S_OK and (*processedSize == 0), + then there are no more bytes in stream. + if (size > 0) && there are bytes in stream, + this function must read at least 1 byte. + This function is allowed to read less than number of remaining bytes in stream. + You must call Read function in loop, if you need exact amount of data + */ }; -// {23170F69-40C1-278A-0000-000000020000} -DEFINE_GUID(IID_ISequentialOutStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000000020000") -ISequentialOutStream : public IUnknown +STREAM_INTERFACE(ISequentialOutStream, 0x02) { -public: - STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) = 0; - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize) = 0; + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE; + /* + if (size > 0) this function must write at least 1 byte. + This function is allowed to write less than "size". + You must call Write function in loop, if you need to write exact amount of data + */ }; -// {23170F69-40C1-278A-0000-000000030000} -DEFINE_GUID(IID_IInStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000000030000") -IInStream : public ISequentialInStream +STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03) { -public: - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0; + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; }; -// {23170F69-40C1-278A-0000-000000040000} -DEFINE_GUID(IID_IOutStream, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000000040000") -IOutStream : public ISequentialOutStream +STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04) { -public: - STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) = 0; - STDMETHOD(SetSize)(Int64 newSize) = 0; + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE; + STDMETHOD(SetSize)(Int64 newSize) PURE; }; -// {23170F69-40C1-278A-0000-000000060000} -DEFINE_GUID(IID_IStreamGetSize, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000000060000") -IStreamGetSize : public IUnknown +STREAM_INTERFACE(IStreamGetSize, 0x06) { -public: - STDMETHOD(GetSize)(UInt64 *size) = 0; + STDMETHOD(GetSize)(UInt64 *size) PURE; }; -// {23170F69-40C1-278A-0000-000000070000} -DEFINE_GUID(IID_IOutStreamFlush, -0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00); -MIDL_INTERFACE("23170F69-40C1-278A-0000-000000070000") -IOutStreamFlush : public IUnknown +STREAM_INTERFACE(IOutStreamFlush, 0x07) { -public: - STDMETHOD(Flush)() = 0; + STDMETHOD(Flush)() PURE; }; #endif diff --git a/7zip/MyVersion.h b/7zip/MyVersion.h index 4f3c3cd4..61f68ccf 100755 --- a/7zip/MyVersion.h +++ b/7zip/MyVersion.h @@ -1,7 +1,7 @@ #define MY_VER_MAJOR 4 -#define MY_VER_MINOR 26 -#define MY_VERSION "4.26 beta" -#define MY_7ZIP_VERSION "7-Zip 4.26 beta" -#define MY_DATE "2005-08-05" +#define MY_VER_MINOR 27 +#define MY_VERSION "4.27 beta" +#define MY_7ZIP_VERSION "7-Zip 4.27 beta" +#define MY_DATE "2005-09-21" #define MY_COPYRIGHT "Copyright (c) 1999-2005 Igor Pavlov" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/7zip/UI/Agent/AgentOut.cpp b/7zip/UI/Agent/AgentOut.cpp index ea556d49..d31d40da 100755 --- a/7zip/UI/Agent/AgentOut.cpp +++ b/7zip/UI/Agent/AgentOut.cpp @@ -154,7 +154,8 @@ STDMETHODIMP CAgent::DoOperation( if (!CanUpdate()) return E_NOTIMPL; NUpdateArchive::CActionSet actionSet; - for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + int i; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i]; CObjectVector<CDirItem> dirItems; @@ -242,7 +243,7 @@ STDMETHODIMP CAgent::DoOperation( } CMyComPtr<ISetProperties> setProperties; - if (outArchive->QueryInterface(&setProperties) == S_OK) + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) { if (m_PropNames.Size() == 0) { diff --git a/7zip/UI/Agent/AgentProxy.cpp b/7zip/UI/Agent/AgentProxy.cpp index a77656bb..23b3e9d1 100755 --- a/7zip/UI/Agent/AgentProxy.cpp +++ b/7zip/UI/Agent/AgentProxy.cpp @@ -98,7 +98,8 @@ void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const { if (IsLeaf) realIndices.Add(Index); - for(int i = 0; i < Folders.Size(); i++) + int i; + for(i = 0; i < Folders.Size(); i++) Folders[i].AddRealIndices(realIndices); for(i = 0; i < Files.Size(); i++) realIndices.Add(Files[i].Index); diff --git a/7zip/UI/Agent/ArchiveFolderOpen.cpp b/7zip/UI/Agent/ArchiveFolderOpen.cpp index 0cc088cf..258e3b77 100755 --- a/7zip/UI/Agent/ArchiveFolderOpen.cpp +++ b/7zip/UI/Agent/ArchiveFolderOpen.cpp @@ -57,9 +57,12 @@ STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types) UString typesStrings; for(int i = 0; i < _formats.Size(); i++) { + const CArchiverInfo &ai = _formats[i]; + if (!ai.Associate) + continue; if (i != 0) typesStrings += L' '; - typesStrings += _formats[i].Name; + typesStrings += ai.Name; } CMyComBSTR valueTemp = typesStrings; *types = valueTemp.Detach(); @@ -72,8 +75,7 @@ STDMETHODIMP CArchiveFolderManager::GetExtension(const wchar_t *type, BSTR *exte int formatIndex = FindFormat(type); if (formatIndex < 0) return E_INVALIDARG; - // CMyComBSTR valueTemp = _formats[formatIndex].GetAllExtensions(); - CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Extension; + CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Ext; *extension = valueTemp.Detach(); return S_OK; } @@ -93,6 +95,3 @@ STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t *type, const { return E_NOTIMPL; } - - - diff --git a/7zip/UI/Client7z/Client7z.cpp b/7zip/UI/Client7z/Client7z.cpp index 970e85a9..90d6cfd3 100755 --- a/7zip/UI/Client7z/Client7z.cpp +++ b/7zip/UI/Client7z/Client7z.cpp @@ -11,9 +11,9 @@ #include "Windows/PropVariantConversions.h" #include "Windows/DLL.h" -// {23170F69-40C1-278A-1000-000110050000} +// {23170F69-40C1-278A-1000-000110070000} DEFINE_GUID(CLSID_CFormat7z, - 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00); + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); typedef UINT32 (WINAPI * CreateObjectFunc)( const GUID *clsID, diff --git a/7zip/UI/Common/ArchiveCommandLine.cpp b/7zip/UI/Common/ArchiveCommandLine.cpp index 70c2d804..3a3a8c33 100755 --- a/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/7zip/UI/Common/ArchiveCommandLine.cpp @@ -691,7 +691,7 @@ static void SetArchiveType(const UString &archiveType, CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {} -void CArchiveCommandLineParser::Parse1(UStringVector commandStrings, +void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options) { try diff --git a/7zip/UI/Common/ArchiveCommandLine.h b/7zip/UI/Common/ArchiveCommandLine.h index d4cacb17..48bf026d 100755 --- a/7zip/UI/Common/ArchiveCommandLine.h +++ b/7zip/UI/Common/ArchiveCommandLine.h @@ -77,7 +77,7 @@ class CArchiveCommandLineParser NCommandLineParser::CParser parser; public: CArchiveCommandLineParser(); - void Parse1(const UStringVector commandStrings, CArchiveCommandLineOptions &options); + void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options); void Parse2(CArchiveCommandLineOptions &options); }; diff --git a/7zip/UI/Common/ArchiverInfo.cpp b/7zip/UI/Common/ArchiverInfo.cpp index 5e88d432..6c7178b3 100755 --- a/7zip/UI/Common/ArchiverInfo.cpp +++ b/7zip/UI/Common/ArchiverInfo.cpp @@ -53,15 +53,6 @@ static void SplitString(const UString &srcString, UStringVector &destStrings) typedef UInt32 (WINAPI * GetHandlerPropertyFunc)( PROPID propID, PROPVARIANT *value); -/* -UString GetCurrentModulePath() -{ - TCHAR fullPath[MAX_PATH + 1]; - ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH); - return fullPath; -} -*/ - static UString GetModuleFolderPrefix() { UString path; @@ -132,7 +123,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) { CArchiverInfo item; item.UpdateEnabled = true; - item.KeepName = false; item.Name = L"7z"; item.Extensions.Add(CArchiverExtInfo(L"7z")); #ifndef _SFX @@ -163,7 +153,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) { CArchiverInfo item; item.UpdateEnabled = true; - item.KeepName = false; item.Name = L"GZip"; item.Extensions.Add(CArchiverExtInfo(L"gz")); item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar")); @@ -190,7 +179,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) { CArchiverInfo item; item.UpdateEnabled = true; - item.KeepName = false; item.Name = L"Tar"; item.Extensions.Add(CArchiverExtInfo(L"tar")); archivers.Add(item); @@ -201,7 +189,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) { CArchiverInfo item; item.UpdateEnabled = true; - item.KeepName = false; item.Name = L"Zip"; item.Extensions.Add(CArchiverExtInfo(L"zip")); #ifndef _SFX @@ -215,7 +202,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) #ifdef FORMAT_CPIO { CArchiverInfo item; - item.UpdateEnabled = false; item.Name = L"Cpio"; item.Extensions.Add(CArchiverExtInfo(L"cpio")); archivers.Add(item); @@ -225,7 +211,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) #ifdef FORMAT_RPM { CArchiverInfo item; - item.UpdateEnabled = false; item.Name = L"Rpm"; item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz")); archivers.Add(item); @@ -235,7 +220,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) #ifdef FORMAT_ARJ { CArchiverInfo item; - item.UpdateEnabled = false; item.Name = L"Arj"; item.Extensions.Add(CArchiverExtInfo(L"arj")); #ifndef _SFX @@ -249,7 +233,6 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) #ifdef FORMAT_Z { CArchiverInfo item; - item.UpdateEnabled = false; item.Name = L"Z"; item.Extensions.Add(CArchiverExtInfo(L"Z")); #ifndef _SFX @@ -309,11 +292,10 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) continue; UString ext = prop.bstrVal; - // item.Extension = prop.bstrVal; - prop.Clear(); - UString addExt; + prop.Clear(); + if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK) continue; if (prop.vt == VT_BSTR) @@ -332,11 +314,11 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) for (int i = 0; i < exts.Size(); i++) { CArchiverExtInfo extInfo; - extInfo.Extension = exts[i]; + extInfo.Ext = exts[i]; if (addExts.Size() > 0) - extInfo.AddExtension = addExts[i]; - if (extInfo.AddExtension == L"*") - extInfo.AddExtension.Empty(); + extInfo.AddExt = addExts[i]; + if (extInfo.AddExt == L"*") + extInfo.AddExt.Empty(); item.Extensions.Add(extInfo); } @@ -364,6 +346,12 @@ void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers) } prop.Clear(); + if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.Associate = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + + archivers.Add(item); } diff --git a/7zip/UI/Common/ArchiverInfo.h b/7zip/UI/Common/ArchiverInfo.h index 0ce057fa..b05d0614 100755 --- a/7zip/UI/Common/ArchiverInfo.h +++ b/7zip/UI/Common/ArchiverInfo.h @@ -9,13 +9,11 @@ struct CArchiverExtInfo { - UString Extension; - UString AddExtension; + UString Ext; + UString AddExt; CArchiverExtInfo() {} - CArchiverExtInfo(const UString &extension): - Extension(extension) {} - CArchiverExtInfo(const UString &extension, const UString &addExtension): - Extension(extension), AddExtension(addExtension) {} + CArchiverExtInfo(const UString &ext): Ext(ext) {} + CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {} }; struct CArchiverInfo @@ -29,11 +27,12 @@ struct CArchiverInfo #ifndef _SFX CByteBuffer StartSignature; CByteBuffer FinishSignature; + bool Associate; #endif int FindExtension(const UString &ext) const { for (int i = 0; i < Extensions.Size(); i++) - if (ext.CollateNoCase(Extensions[i].Extension) == 0) + if (ext.CollateNoCase(Extensions[i].Ext) == 0) return i; return -1; } @@ -44,16 +43,22 @@ struct CArchiverInfo { if (i > 0) s += ' '; - s += Extensions[i].Extension; + s += Extensions[i].Ext; } return s; } const UString &GetMainExtension() const { - return Extensions[0].Extension; + return Extensions[0].Ext; } bool UpdateEnabled; bool KeepName; + + CArchiverInfo(): UpdateEnabled(false), KeepName(false) + #ifndef _SFX + ,Associate(true) + #endif + {} }; void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers); diff --git a/7zip/UI/Common/EnumDirItems.cpp b/7zip/UI/Common/EnumDirItems.cpp index f4212e95..dddc05a9 100755 --- a/7zip/UI/Common/EnumDirItems.cpp +++ b/7zip/UI/Common/EnumDirItems.cpp @@ -226,8 +226,11 @@ static HRESULT EnumerateDirItems( bool enterToSubFolders2 = enterToSubFolders; UStringVector addArchivePrefixNew = addArchivePrefix; addArchivePrefixNew.Add(name); - if (curNode.CheckPathToRoot(false, UStringVector(addArchivePrefixNew), !fileInfo.IsDirectory())) - continue; + { + UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); + if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory())) + continue; + } if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory())) { AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems); diff --git a/7zip/UI/Common/Extract.h b/7zip/UI/Common/Extract.h index e124d466..8823b08b 100755 --- a/7zip/UI/Common/Extract.h +++ b/7zip/UI/Common/Extract.h @@ -7,7 +7,6 @@ #include "Windows/FileFind.h" #include "../../Archive/IArchive.h" -#include "../Common/ZipRegistry.h" #include "ArchiveExtractCallback.h" #include "ArchiveOpenCallback.h" diff --git a/7zip/UI/Common/OpenArchive.cpp b/7zip/UI/Common/OpenArchive.cpp index 91339d47..88a231a4 100755 --- a/7zip/UI/Common/OpenArchive.cpp +++ b/7zip/UI/Common/OpenArchive.cpp @@ -12,6 +12,7 @@ #include "Windows/PropVariant.h" #include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" #include "Common/StringConvert.h" @@ -179,7 +180,7 @@ HRESULT OpenArchive( Byte *buffer = byteBuffer; RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); UInt32 processedSize; - RINOK(inStream->Read(buffer, kBufferSize, &processedSize)); + RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize)); int numFinded = 0; for (int pos = (int)processedSize; pos >= 0 ; pos--) { @@ -281,8 +282,8 @@ HRESULT OpenArchive( if (subExtIndex < 0) subExtIndex = 0; defaultItemName = GetDefaultName2(fileName, - archiverInfo.Extensions[subExtIndex].Extension, - archiverInfo.Extensions[subExtIndex].AddExtension); + archiverInfo.Extensions[subExtIndex].Ext, + archiverInfo.Extensions[subExtIndex].AddExt); return S_OK; } diff --git a/7zip/UI/Common/SortUtils.cpp b/7zip/UI/Common/SortUtils.cpp index 1c647d53..8c953750 100755 --- a/7zip/UI/Common/SortUtils.cpp +++ b/7zip/UI/Common/SortUtils.cpp @@ -4,29 +4,22 @@ #include "SortUtils.h" -static int __cdecl CompareStrings(const void *a1, const void *a2) +static int CompareStrings(const int *p1, const int *p2, void *param) { - const UString &s1 = *(*(*((const UString ***)a1))); - const UString &s2 = *(*(*((const UString ***)a2))); + const UStringVector &strings = *(const UStringVector *)param; + const UString &s1 = strings[*p1]; + const UString &s2 = strings[*p2]; return s1.CompareNoCase(s2); } void SortStringsToIndices(const UStringVector &strings, CIntVector &indices) { indices.Clear(); - if (strings.IsEmpty()) - return; int numItems = strings.Size(); - CPointerVector pointers; - pointers.Reserve(numItems); indices.Reserve(numItems); - int i; - for(i = 0; i < numItems; i++) - pointers.Add((void *)&strings.CPointerVector::operator[](i)); - void **stringsBase = (void **)pointers[0]; - qsort(&pointers[0], numItems, sizeof(void *), CompareStrings); - for(i = 0; i < numItems; i++) - indices.Add((int)((void **)pointers[i] - stringsBase)); + for(int i = 0; i < numItems; i++) + indices.Add(i); + indices.Sort(CompareStrings, (void *)&strings); } void SortStrings(const UStringVector &src, UStringVector &dest) diff --git a/7zip/UI/Common/Update.cpp b/7zip/UI/Common/Update.cpp index e2fde3de..a241c9c4 100755 --- a/7zip/UI/Common/Update.cpp +++ b/7zip/UI/Common/Update.cpp @@ -129,7 +129,6 @@ public: MY_UNKNOWN_IMP1(IOutStream) STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); - STDMETHOD(WritePart)(const void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(SetSize)(Int64 newSize); }; @@ -207,17 +206,13 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr _streamIndex++; _offsetPos = 0; } - if (realProcessed != curSize) + if (realProcessed == 0 && curSize != 0) return E_FAIL; + break; } return S_OK; } -STDMETHODIMP COutMultiVolStream::WritePart(const void *data, UInt32 size, UInt32 *processedSize) -{ - return Write(data, size, processedSize); -} - STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) { if(seekOrigin >= 3) diff --git a/7zip/UI/Console/Console.dsp b/7zip/UI/Console/Console.dsp index f6764fa1..29f10b2f 100755 --- a/7zip/UI/Console/Console.dsp +++ b/7zip/UI/Console/Console.dsp @@ -618,6 +618,14 @@ SOURCE=..\..\Common\FileStreams.cpp SOURCE=..\..\Common\FileStreams.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Compress" diff --git a/7zip/UI/Console/Main.cpp b/7zip/UI/Console/Main.cpp index 3f000188..a72bfca7 100755 --- a/7zip/UI/Console/Main.cpp +++ b/7zip/UI/Console/Main.cpp @@ -91,7 +91,7 @@ static const char *kHelpString = " -si: read data from stdin\n" " -so: write data to stdout\n" " -t{Type}: Set type of archive\n" - " -v{Size}}[b|k|m|g]: Create volumes\n" + " -v{Size}[b|k|m|g]: Create volumes\n" " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n" " -w[{path}]: assign Work directory. Empty path means a temporary directory\n" " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n" @@ -232,6 +232,8 @@ int Main2( if (ecs->NumFileErrors != 0) stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl; } + if (result != S_OK) + throw CSystemException(result); return NExitCode::kFatalError; } if (result != S_OK) diff --git a/7zip/UI/Console/makefile b/7zip/UI/Console/makefile index b5f97e48..b9a5ef0b 100755 --- a/7zip/UI/Console/makefile +++ b/7zip/UI/Console/makefile @@ -42,6 +42,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveCommandLine.obj \ diff --git a/7zip/UI/Explorer/ContextMenu.cpp b/7zip/UI/Explorer/ContextMenu.cpp index 06465e86..94cf1bd4 100755 --- a/7zip/UI/Explorer/ContextMenu.cpp +++ b/7zip/UI/Explorer/ContextMenu.cpp @@ -583,6 +583,7 @@ struct CThreadCompressMain }; */ +#ifndef _WIN64 static bool IsItWindowsNT() { OSVERSIONINFO versionInfo; @@ -591,6 +592,7 @@ static bool IsItWindowsNT() return false; return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); } +#endif static UString GetProgramCommand() { @@ -598,11 +600,12 @@ static UString GetProgramCommand() UString folder; if (GetProgramFolderPath(folder)) path += folder; + path += L"7zFM"; + #ifndef _WIN64 if (IsItWindowsNT()) - path += L"7zFMn.exe"; - else - path += L"7zFM.exe"; - path += L"\""; + path += L"n"; + #endif + path += L".exe\""; return path; } diff --git a/7zip/UI/Explorer/Explorer.dsp b/7zip/UI/Explorer/Explorer.dsp index 371c9ac4..34555372 100755 --- a/7zip/UI/Explorer/Explorer.dsp +++ b/7zip/UI/Explorer/Explorer.dsp @@ -744,6 +744,14 @@ SOURCE=..\..\Common\FileStreams.cpp SOURCE=..\..\Common\FileStreams.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Compress" diff --git a/7zip/UI/Explorer/makefile b/7zip/UI/Explorer/makefile index 99059538..d1938716 100755 --- a/7zip/UI/Explorer/makefile +++ b/7zip/UI/Explorer/makefile @@ -50,6 +50,7 @@ WIN_CTRL_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveExtractCallback.obj \ diff --git a/7zip/UI/Far/Far.dsp b/7zip/UI/Far/Far.dsp index dab36478..47c44c69 100755 --- a/7zip/UI/Far/Far.dsp +++ b/7zip/UI/Far/Far.dsp @@ -548,6 +548,14 @@ SOURCE=..\..\Common\FileStreams.cpp SOURCE=..\..\Common\FileStreams.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # End Target # End Project diff --git a/7zip/UI/Far/Messages.h b/7zip/UI/Far/Messages.h index a0f1098c..8b6e2a49 100755 --- a/7zip/UI/Far/Messages.h +++ b/7zip/UI/Far/Messages.h @@ -63,6 +63,7 @@ enum EEnum kExtractOwerwritePrompt, kExtractOwerwriteSkip, kExtractOwerwriteAutoRename, + kExtractOwerwriteAutoRenameExisting, kExtractFilesMode, kExtractFilesSelected, diff --git a/7zip/UI/Far/PluginRead.cpp b/7zip/UI/Far/PluginRead.cpp index e9b6f98c..79409142 100755 --- a/7zip/UI/Far/PluginRead.cpp +++ b/7zip/UI/Far/PluginRead.cpp @@ -112,19 +112,22 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa const int kPathModeRadioIndex = 4; const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4; - const int kFilesModeIndex = kOverwriteModeRadioIndex + 5; - const int kYSize = 18; + const int kNumOverwriteOptions = 6; + const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions; + const int kXSize = 76; + const int kYSize = 19; + const int kPasswordYPos = 12; - const int kXMid = 38; + const int kXMid = kXSize / 2; AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP); struct CInitDialogItem initItems[]={ - { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL }, + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL }, { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL }, - { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName}, - // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, destPath, NULL}, + { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName}, + // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL}, { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL }, { DI_RADIOBUTTON, 6, 6, 0, 0, false, @@ -137,7 +140,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames, false, 0, NMessageID::kExtractPathNo, NULL, NULL }, - { DI_SINGLEBOX, kXMid, 5, 70, 5 + 5, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL }, + { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL }, { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAskBefore, DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL }, @@ -150,13 +153,16 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false, extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRename, 0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting, + 0, false, NMessageID::kExtractOwerwriteAutoRenameExisting, NULL, NULL }, { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL }, { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL }, { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL }, - { DI_SINGLEBOX, kXMid, 11, 70, 11 + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL }, - { DI_PSWEDIT, kXMid + 2, 12, 70 - 2, 12, false, false, 0, false, -1, oemPassword, NULL}, + { DI_SINGLEBOX, kXMid, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL }, + { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL}, { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, @@ -173,7 +179,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); while(true) { - int askCode = g_StartupInfo.ShowDialog(76, kYSize, + int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize, kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems); if (askCode != kOkButtonIndex) return NFileOperationReturnCode::kInterruptedByUser; @@ -211,6 +217,8 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected) extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRename; + else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRenameExisting; else throw 31806; @@ -247,41 +255,8 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa for (int i = 0; i < itemsNumber; i++) indices.Add(panelItems[i].UserData); - NExtract::NPathMode::EEnum pathMode; - NExtract::NOverwriteMode::EEnum overwriteMode; - switch (extractionInfo.OverwriteMode) - { - case NExtract::NOverwriteMode::kAskBefore: - overwriteMode = NExtract::NOverwriteMode::kAskBefore; - break; - case NExtract::NOverwriteMode::kWithoutPrompt: - overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; - break; - case NExtract::NOverwriteMode::kSkipExisting: - overwriteMode = NExtract::NOverwriteMode::kSkipExisting; - break; - case NExtract::NOverwriteMode::kAutoRename: - overwriteMode = NExtract::NOverwriteMode::kAutoRename; - break; - default: - throw 12334454; - } - switch (extractionInfo.PathMode) - { - case NExtract::NPathMode::kFullPathnames: - pathMode = NExtract::NPathMode::kFullPathnames; - break; - case NExtract::NPathMode::kCurrentPathnames: - pathMode = NExtract::NPathMode::kCurrentPathnames; - break; - case NExtract::NPathMode::kNoPathnames: - pathMode = NExtract::NPathMode::kNoPathnames; - break; - default: - throw 12334455; - } HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber, - !showBox, pathMode, overwriteMode, + !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode, MultiByteToUnicodeString(destPath, CP_OEMCP), passwordIsDefined, password); // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox, diff --git a/7zip/UI/Far/PluginWrite.cpp b/7zip/UI/Far/PluginWrite.cpp index e9581c59..0342be2e 100755 --- a/7zip/UI/Far/PluginWrite.cpp +++ b/7zip/UI/Far/PluginWrite.cpp @@ -40,7 +40,7 @@ static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 }; static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method) { CMyComPtr<ISetProperties> setProperties; - if (outArchive->QueryInterface(&setProperties) == S_OK) + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) { UStringVector realNames; realNames.Add(UString(L"x")); diff --git a/7zip/UI/Far/makefile b/7zip/UI/Far/makefile index 5b9d8bcd..d5819130 100755 --- a/7zip/UI/Far/makefile +++ b/7zip/UI/Far/makefile @@ -42,6 +42,7 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveExtractCallback.obj \ diff --git a/7zip/UI/GUI/CompressDialog.cpp b/7zip/UI/GUI/CompressDialog.cpp index 7bb40248..2a0147c3 100755 --- a/7zip/UI/GUI/CompressDialog.cpp +++ b/7zip/UI/GUI/CompressDialog.cpp @@ -509,20 +509,8 @@ void CCompressDialog::OnOK() _passwordControl.GetText(Info.Password); SaveOptionsInMem(); - int currentItem = m_ArchivePath.GetCurSel(); UString s; - if(currentItem == CB_ERR) - { - m_ArchivePath.GetText(s); - if(m_ArchivePath.GetCount() >= kHistorySize) - currentItem = m_ArchivePath.GetCount() - 1; - } - else - { - CSysString sTemp; - m_ArchivePath.GetLBText(currentItem, sTemp); - s = GetUnicodeString(sTemp); - } + m_ArchivePath.GetText(s); s.Trim(); m_RegistryInfo.HistoryArchives.Clear(); AddUniqueString(m_RegistryInfo.HistoryArchives, GetSystemString(s)); @@ -555,13 +543,14 @@ void CCompressDialog::OnOK() } for(int i = 0; i < m_ArchivePath.GetCount(); i++) - if(i != currentItem) - { - CSysString sTemp; - m_ArchivePath.GetLBText(i, sTemp); - sTemp.Trim(); - AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp); - } + { + CSysString sTemp; + m_ArchivePath.GetLBText(i, sTemp); + sTemp.Trim(); + AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp); + } + if (m_RegistryInfo.HistoryArchives.Size() > kHistorySize) + m_RegistryInfo.HistoryArchives.DeleteBack(); //////////////////// // Method diff --git a/7zip/UI/GUI/GUI.dsp b/7zip/UI/GUI/GUI.dsp index 3473cc76..e8db155c 100755 --- a/7zip/UI/GUI/GUI.dsp +++ b/7zip/UI/GUI/GUI.dsp @@ -847,6 +847,14 @@ SOURCE=..\..\Common\FileStreams.cpp SOURCE=..\..\Common\FileStreams.h # End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File # End Group # Begin Group "Compress" diff --git a/7zip/UI/GUI/makefile b/7zip/UI/GUI/makefile index cfe1493c..20c6caaa 100755 --- a/7zip/UI/GUI/makefile +++ b/7zip/UI/GUI/makefile @@ -50,6 +50,7 @@ WIN_CTRL_OBJS = \ 7ZIP_COMMON_OBJS = \ $O\FilePathAutoRename.obj \ $O\FileStreams.obj \ + $O\StreamUtils.obj \ UI_COMMON_OBJS = \ $O\ArchiveCommandLine.obj \ @@ -1,5 +1,6 @@ !IFDEF CPU LIBS = $(LIBS) bufferoverflowU.lib +CFLAGS = $(CFLAGS) -GS- -Zc:forScope !ENDIF !IFNDEF O @@ -10,7 +11,7 @@ O=O !ENDIF !ENDIF -CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -GS- +CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -WX !IFDEF MY_STATIC_LINK !IFNDEF MY_SINGLE_THREAD CFLAGS = $(CFLAGS) -MT diff --git a/Common/Buffer.h b/Common/Buffer.h index 9d5fcaec..9bd881cf 100755 --- a/Common/Buffer.h +++ b/Common/Buffer.h @@ -26,6 +26,8 @@ public: size_t GetCapacity() const { return _capacity; } void SetCapacity(size_t newCapacity) { + if (newCapacity == _capacity) + return; T *newBuffer; if (newCapacity > 0) { diff --git a/Common/Copy of StringConvert.cpp b/Common/Copy of StringConvert.cpp deleted file mode 100755 index d6d05d6c..00000000 --- a/Common/Copy of StringConvert.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Common/StringConvert.cpp - -#include "StdAfx.h" - -#include "StringConvert.h" - -#ifndef _WIN32 -#include <stdlib.h> -#endif - -#ifdef _WIN32 -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) -{ - UString resultString; - if(!srcString.IsEmpty()) - { - int numChars = MultiByteToWideChar(codePage, 0, srcString, - srcString.Length(), resultString.GetBuffer(srcString.Length()), - srcString.Length() + 1); - #ifndef _WIN32_WCE - if(numChars == 0) - throw 282228; - #endif - resultString.ReleaseBuffer(numChars); - } - return resultString; -} - -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) -{ - AString resultString; - if(!srcString.IsEmpty()) - { - int numRequiredBytes = srcString.Length() * 2; - int numChars = WideCharToMultiByte(codePage, 0, srcString, - srcString.Length(), resultString.GetBuffer(numRequiredBytes), - numRequiredBytes + 1, NULL, NULL); - #ifndef _WIN32_WCE - if(numChars == 0) - throw 282229; - #endif - resultString.ReleaseBuffer(numChars); - } - return resultString; -} - -#ifndef _WIN32_WCE -AString SystemStringToOemString(const CSysString &srcString) -{ - AString result; - CharToOem(srcString, result.GetBuffer(srcString.Length() * 2)); - result.ReleaseBuffer(); - return result; -} -#endif - -#else - -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) -{ - UString resultString; - for (int i = 0; i < srcString.Length(); i++) - resultString += wchar_t(srcString[i]); - /* - if(!srcString.IsEmpty()) - { - int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1); - if (numChars < 0) throw "Your environment does not support UNICODE"; - resultString.ReleaseBuffer(numChars); - } - */ - return resultString; -} - -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage) -{ - AString resultString; - for (int i = 0; i < srcString.Length(); i++) - resultString += char(srcString[i]); - /* - if(!srcString.IsEmpty()) - { - int numRequiredBytes = srcString.Length() * 6 + 1; - int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes); - if (numChars < 0) throw "Your environment does not support UNICODE"; - resultString.ReleaseBuffer(numChars); - } - */ - return resultString; -} - -#endif - diff --git a/Common/Copy of StringConvert.h b/Common/Copy of StringConvert.h deleted file mode 100755 index daee50b0..00000000 --- a/Common/Copy of StringConvert.h +++ /dev/null @@ -1,71 +0,0 @@ -// Common/StringConvert.h - -#ifndef __COMMON_STRINGCONVERT_H -#define __COMMON_STRINGCONVERT_H - -#include "MyWindows.h" -#include "Common/String.h" -#include "Types.h" - -UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP); -AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP); - -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString) - { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString) - { return unicodeString; } -inline UString GetUnicodeString(const AString &ansiString) - { return MultiByteToUnicodeString(ansiString); } -inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) - { return MultiByteToUnicodeString(multiByteString, codePage); } -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT codePage) - { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage) - { return unicodeString; } - -inline const char* GetAnsiString(const char* ansiString) - { return ansiString; } -inline const AString& GetAnsiString(const AString &ansiString) - { return ansiString; } -inline AString GetAnsiString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString); } - -inline const char* GetOemString(const char* oemString) - { return oemString; } -inline const AString& GetOemString(const AString &oemString) - { return oemString; } -inline AString GetOemString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); } - - -#ifdef _UNICODE - inline const wchar_t* GetSystemString(const wchar_t* unicodeString) - { return unicodeString;} - inline const UString& GetSystemString(const UString &unicodeString) - { return unicodeString;} - inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT codePage) - { return unicodeString;} - inline const UString& GetSystemString(const UString &unicodeString, UINT codePage) - { return unicodeString;} - inline UString GetSystemString(const AString &multiByteString, UINT codePage) - { return MultiByteToUnicodeString(multiByteString, codePage);} - inline UString GetSystemString(const AString &multiByteString) - { return MultiByteToUnicodeString(multiByteString);} -#else - inline const char* GetSystemString(const char *ansiString) - { return ansiString; } - inline const AString& GetSystemString(const AString &multiByteString, UINT codePage) - { return multiByteString; } - inline const char * GetSystemString(const char *multiByteString, UINT codePage) - { return multiByteString; } - inline AString GetSystemString(const UString &unicodeString) - { return UnicodeStringToMultiByte(unicodeString); } - inline AString GetSystemString(const UString &unicodeString, UINT codePage) - { return UnicodeStringToMultiByte(unicodeString, codePage); } -#endif - -#ifndef _WIN32_WCE -AString SystemStringToOemString(const CSysString &srcString); -#endif - -#endif diff --git a/Common/Copy of UTFConvert.cpp b/Common/Copy of UTFConvert.cpp deleted file mode 100755 index e15695bb..00000000 --- a/Common/Copy of UTFConvert.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// UTFConvert.cpp - -#include "StdAfx.h" - -#include "UTFConvert.h" -#include "Types.h" - -static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -// These functions are for UTF8 <-> UTF16 conversion. - -bool ConvertUTF8ToUnicode(const AString &src, UString &dest) -{ - dest.Empty(); - for(int i = 0; i < src.Length();) - { - Byte c = (Byte)src[i++]; - if (c < 0x80) - { - dest += (wchar_t)c; - continue; - } - if(c < 0xC0) - return false; - int numAdds; - for (numAdds = 1; numAdds < 5; numAdds++) - if (c < kUtf8Limits[numAdds]) - break; - UInt32 value = (c - kUtf8Limits[numAdds - 1]); - do - { - if (i >= src.Length()) - return false; - Byte c2 = (Byte)src[i++]; - if (c2 < 0x80 || c2 >= 0xC0) - return false; - value <<= 6; - value |= (c2 - 0x80); - numAdds--; - } - while(numAdds > 0); - if (value < 0x10000) - dest += (wchar_t)(value); - else - { - value -= 0x10000; - if (value >= 0x100000) - return false; - dest += (wchar_t)(0xD800 + (value >> 10)); - dest += (wchar_t)(0xDC00 + (value & 0x3FF)); - } - } - return true; -} - -bool ConvertUnicodeToUTF8(const UString &src, AString &dest) -{ - dest.Empty(); - for(int i = 0; i < src.Length();) - { - UInt32 value = (UInt32)src[i++]; - if (value < 0x80) - { - dest += (char)value; - continue; - } - if (value >= 0xD800 && value < 0xE000) - { - if (value >= 0xDC00) - return false; - if (i >= src.Length()) - return false; - UInt32 c2 = (UInt32)src[i++]; - if (c2 < 0xDC00 || c2 >= 0xE000) - return false; - value = ((value - 0xD800) << 10) | (c2 - 0xDC00); - } - int numAdds; - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((UInt32)1) << (numAdds * 5 + 6))) - break; - dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds))); - do - { - numAdds--; - dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F)); - } - while(numAdds > 0); - } - return true; -} diff --git a/Common/Copy of UTFConvert.h b/Common/Copy of UTFConvert.h deleted file mode 100755 index 47434111..00000000 --- a/Common/Copy of UTFConvert.h +++ /dev/null @@ -1,11 +0,0 @@ -// Common/UTFConvert.h - -#ifndef __COMMON_UTFCONVERT_H -#define __COMMON_UTFCONVERT_H - -#include "Common/String.h" - -bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString); -bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString); - -#endif diff --git a/Common/MyCom.h b/Common/MyCom.h index 4101d815..e9034930 100755 --- a/Common/MyCom.h +++ b/Common/MyCom.h @@ -166,7 +166,9 @@ STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \ MY_ADDREF_RELEASE -#define MY_UNKNOWN_IMP MY_UNKNOWN_IMP_SPEC(;) +#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE #define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \ MY_QUERYINTERFACE_ENTRY(i) \ diff --git a/Common/MyGuidDef.h b/Common/MyGuidDef.h index 2fb7df65..2c954f81 100755 --- a/Common/MyGuidDef.h +++ b/Common/MyGuidDef.h @@ -3,10 +3,12 @@ #ifndef GUID_DEFINED #define GUID_DEFINED +#include "Types.h" + typedef struct { - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; unsigned char Data4[8]; } GUID; diff --git a/Common/MyWindows.h b/Common/MyWindows.h index d93afc1c..6df08d6f 100755 --- a/Common/MyWindows.h +++ b/Common/MyWindows.h @@ -12,7 +12,6 @@ #include <stddef.h> // for wchar_t #include <string.h> -#include "Types.h" #include "MyGuidDef.h" typedef char CHAR; diff --git a/Common/String.h b/Common/String.h index 56509016..a34e8347 100755 --- a/Common/String.h +++ b/Common/String.h @@ -34,9 +34,9 @@ inline wchar_t* MyStringGetNextCharPointer(wchar_t *p) { return (p + 1); } inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p) { return (p + 1); } -inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, wchar_t *p) +inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p) { return (p - 1); } -inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *base, const wchar_t *p) +inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p) { return (p - 1); } #ifdef _WIN32 diff --git a/Common/StringConvert.h b/Common/StringConvert.h index daee50b0..648ca028 100755 --- a/Common/StringConvert.h +++ b/Common/StringConvert.h @@ -18,9 +18,9 @@ inline UString GetUnicodeString(const AString &ansiString) { return MultiByteToUnicodeString(ansiString); } inline UString GetUnicodeString(const AString &multiByteString, UINT codePage) { return MultiByteToUnicodeString(multiByteString, codePage); } -inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT codePage) +inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT) { return unicodeString; } -inline const UString& GetUnicodeString(const UString &unicodeString, UINT codePage) +inline const UString& GetUnicodeString(const UString &unicodeString, UINT) { return unicodeString; } inline const char* GetAnsiString(const char* ansiString) @@ -54,9 +54,9 @@ inline AString GetOemString(const UString &unicodeString) #else inline const char* GetSystemString(const char *ansiString) { return ansiString; } - inline const AString& GetSystemString(const AString &multiByteString, UINT codePage) + inline const AString& GetSystemString(const AString &multiByteString, UINT) { return multiByteString; } - inline const char * GetSystemString(const char *multiByteString, UINT codePage) + inline const char * GetSystemString(const char *multiByteString, UINT) { return multiByteString; } inline AString GetSystemString(const UString &unicodeString) { return UnicodeStringToMultiByte(unicodeString); } diff --git a/Common/StringToInt.cpp b/Common/StringToInt.cpp index 9f02ec9d..1fa8ef21 100755 --- a/Common/StringToInt.cpp +++ b/Common/StringToInt.cpp @@ -22,6 +22,25 @@ UInt64 ConvertStringToUInt64(const char *s, const char **end) } } +UInt64 ConvertOctStringToUInt64(const char *s, const char **end) +{ + UInt64 result = 0; + while(true) + { + char c = *s; + if (c < '0' || c > '7') + { + if (end != NULL) + *end = s; + return result; + } + result <<= 3; + result += (c - '0'); + s++; + } +} + + UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end) { UInt64 result = 0; diff --git a/Common/StringToInt.h b/Common/StringToInt.h index f3fc22e8..bb971f62 100755 --- a/Common/StringToInt.h +++ b/Common/StringToInt.h @@ -7,6 +7,7 @@ #include "Types.h" UInt64 ConvertStringToUInt64(const char *s, const char **end); +UInt64 ConvertOctStringToUInt64(const char *s, const char **end); UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end); Int64 ConvertStringToInt64(const char *s, const char **end); diff --git a/Common/Vector.h b/Common/Vector.h index 858e53d3..984fddc1 100755 --- a/Common/Vector.h +++ b/Common/Vector.h @@ -70,14 +70,46 @@ public: T& Front() { return operator[](0); } const T& Back() const { return operator[](_size - 1); } T& Back() { return operator[](_size - 1); } - static int - #ifdef _MSC_VER - __cdecl - #endif - CompareRecordItems(const void *a1, const void *a2) - { return MyCompare(*((const T *)a1), *((const T *)a2)); } - void Sort() - { qsort(&Front(), Size(), _itemSize, CompareRecordItems); } + + void Swap(int i, int j) + { + T temp = operator[](i); + operator[](i) = operator[](j); + operator[](j) = temp; + } + + void Sort(int left, int right) + { + if (right - left < 2) + return; + Swap(left, (left + right) / 2); + int last = left; + for (int i = left; i < right; i++) + if (operator[](i) < operator[](left)) + Swap(++last, i); + Swap(left, last); + Sort(left, last); + Sort(last + 1, right); + } + void Sort() { Sort(0, Size()); } + void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param) + { + if (right - left < 2) + return; + Swap(left, (left + right) / 2); + int last = left; + for (int i = left; i < right; i++) + if (compare(&operator[](i), &operator[](left), param) < 0) + Swap(++last, i); + Swap(left, last); + Sort(left, last, compare, param); + Sort(last + 1, right, compare, param); + } + + void Sort(int (*compare)(const T*, const T*, void *), void *param) + { + Sort(0, Size(), compare, param); + } }; typedef CRecordVector<int> CIntVector; @@ -167,17 +199,13 @@ public: Insert(right, item); return right; } - static int - #ifdef _MSC_VER - __cdecl - #endif - CompareObjectItems(const void *a1, const void *a2) + + void Sort(int (*compare)(void *const *, void *const *, void *), void *param) + { CPointerVector::Sort(compare, param); } + + static int CompareObjectItems(void *const *a1, void *const *a2, void *param) { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } - void Sort() - { - CPointerVector &pointerVector = *this; - qsort(&pointerVector[0], Size(), sizeof(void *), CompareObjectItems); - } + void Sort() { CPointerVector::Sort(CompareObjectItems, 0); } }; #endif diff --git a/DOC/7zFormat.txt b/DOC/7zFormat.txt index 045fc853..56ff817c 100755 --- a/DOC/7zFormat.txt +++ b/DOC/7zFormat.txt @@ -171,8 +171,8 @@ SignatureHeader ArchiveVersion { - BYTE Major; // now it = 0 - BYTE Minor; // now it = 1 + BYTE Major; // now = 0 + BYTE Minor; // now = 2 }; UINT32 StartHeaderCRC; diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi index d6c532b8..ec91560a 100755 --- a/DOC/7zip.nsi +++ b/DOC/7zip.nsi @@ -2,10 +2,30 @@ ;Defines !define VERSION_MAJOR 4 -!define VERSION_MINOR 24 +!define VERSION_MINOR 27 !define VERSION_POSTFIX_FULL " beta" -!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}" +!ifdef WIN64 +!ifdef IA64 +!define VERSION_SYS_POSTFIX_FULL " for Windows IA-64" +!else +!define VERSION_SYS_POSTFIX_FULL " for Windows x64" +!endif +!else +!define VERSION_SYS_POSTFIX_FULL "" +!endif +!define NAME_FULL "7-Zip ${VERSION_MAJOR}.${VERSION_MINOR}${VERSION_POSTFIX_FULL}${VERSION_SYS_POSTFIX_FULL}" !define VERSION_POSTFIX "" +!ifdef WIN64 +!ifdef IA64 +!define VERSION_SYS_POSTFIX "-ia64" +!else +!define VERSION_SYS_POSTFIX "-x64" +!endif +!else +!define VERSION_SYS_POSTFIX "" +!endif + + !define FM_LINK "7-Zip File Manager.lnk" !define HELP_LINK "7-Zip Help.lnk" @@ -23,7 +43,7 @@ ;General Name "${NAME_FULL}" BrandingText "www.7-zip.org" - OutFile "..\7z${VERSION_MAJOR}${VERSION_MINOR}${VERSION_POSTFIX}.exe" + OutFile "..\7z${VERSION_MAJOR}${VERSION_MINOR}${VERSION_POSTFIX}${VERSION_SYS_POSTFIX}.exe" ;Folder selection page InstallDir "$PROGRAMFILES\7-Zip" @@ -34,7 +54,11 @@ ;Compressor !ifndef NO_COMPRESSION SetCompressor /SOLID lzma +!ifdef IA64 + SetCompressorDictSize 8 +!else SetCompressorDictSize 4 +!endif !else SetCompressor zlib SetCompress off @@ -97,16 +121,22 @@ Section File License.txt File copying.txt File readme.txt + !ifndef WIN64 File 7zip_pad.xml + !endif # File 7-zip.dll # File 7-zipn.dll File 7zFM.exe + !ifndef WIN64 File 7zFMn.exe + !endif File 7z.exe File 7za.exe File 7zg.exe + !ifndef WIN64 File 7zgn.exe + !endif File 7z.sfx File 7zCon.sfx @@ -120,9 +150,11 @@ Section File arj.dll File bz2.dll File cab.dll + File chm.dll File cpio.dll File deb.dll File gz.dll + File lzh.dll File rar.dll File rpm.dll File split.dll @@ -172,6 +204,7 @@ Section File hr.txt File hu.txt File id.txt + File io.txt File it.txt File ja.txt File ka.txt @@ -195,6 +228,7 @@ Section File ta.txt File th.txt File tr.txt + File tt.txt File uk.txt File uz.txt File va.txt @@ -215,6 +249,13 @@ Section SetShellVarContext all + !ifdef WIN64 + + !insertmacro InstallLib DLL NOTSHARED REBOOT_NOTPROTECTED 7-zip.dll $INSTDIR\7-zip.dll $INSTDIR + StrCpy "$MyDllPath" "7-zip.dll" + + !else + StrCpy $0 0 System::Call "kernel32::GetVersion() i .r0" IntCmpU $0 0x80000000 0 regNT 0 @@ -228,14 +269,22 @@ Section StrCpy "$MyDllPath" "7-zipn.dll" doneReg: + !endif + ClearErrors # create start menu icons SetOutPath $INSTDIR # working directory CreateDirectory $SMPROGRAMS\7-Zip + + !ifdef WIN64 + StrCpy $1 "" + !else StrCpy $1 "n" IntCmpU $0 0x80000000 0 +2 0 StrCpy $1 "" + !endif + CreateShortcut "$SMPROGRAMS\7-Zip\${FM_LINK}" $INSTDIR\7zFM$1.exe CreateShortcut "$SMPROGRAMS\7-Zip\${HELP_LINK}" $INSTDIR\7-zip.chm @@ -270,8 +319,10 @@ Section WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" "" "$INSTDIR\7zFM.exe" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" "Path" "$INSTDIR" + !ifndef WIN64 WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" "" "$INSTDIR\7zFMn.exe" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" "Path" "$INSTDIR" + !endif # create uninstaller WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "DisplayName" "${NAME_FULL}" @@ -280,6 +331,10 @@ Section WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" "NoRepair" 1 WriteUninstaller $INSTDIR\Uninstall.exe + !ifdef WIN64 + ExecWait 'regsvr32 /s "$INSTDIR\7-zip.dll"' + !endif + SectionEnd @@ -310,13 +365,19 @@ Section "Uninstall" Delete $INSTDIR\7zip_pad.xml Delete /REBOOTOK $INSTDIR\7-zip.dll + !ifndef WIN64 Delete /REBOOTOK $INSTDIR\7-zipn.dll + !endif Delete $INSTDIR\7zFM.exe + !ifndef WIN64 Delete $INSTDIR\7zFMn.exe + !endif Delete $INSTDIR\7z.exe Delete $INSTDIR\7za.exe Delete $INSTDIR\7zg.exe + !ifndef WIN64 Delete $INSTDIR\7zgn.exe + !endif Delete $INSTDIR\7z.sfx Delete $INSTDIR\7zCon.sfx @@ -328,9 +389,11 @@ Section "Uninstall" Delete $INSTDIR\Formats\arj.dll Delete $INSTDIR\Formats\bz2.dll Delete $INSTDIR\Formats\cab.dll + Delete $INSTDIR\Formats\chm.dll Delete $INSTDIR\Formats\cpio.dll Delete $INSTDIR\Formats\deb.dll Delete $INSTDIR\Formats\gz.dll + Delete $INSTDIR\Formats\lzh.dll Delete $INSTDIR\Formats\rar.dll Delete $INSTDIR\Formats\rpm.dll Delete $INSTDIR\Formats\split.dll @@ -380,6 +443,7 @@ Section "Uninstall" Delete $INSTDIR\Lang\hr.txt Delete $INSTDIR\Lang\hu.txt Delete $INSTDIR\Lang\id.txt + Delete $INSTDIR\Lang\io.txt Delete $INSTDIR\Lang\it.txt Delete $INSTDIR\Lang\ja.txt Delete $INSTDIR\Lang\ka.txt @@ -403,6 +467,7 @@ Section "Uninstall" Delete $INSTDIR\Lang\ta.txt Delete $INSTDIR\Lang\th.txt Delete $INSTDIR\Lang\tr.txt + Delete $INSTDIR\Lang\tt.txt Delete $INSTDIR\Lang\uk.txt Delete $INSTDIR\Lang\uz.txt Delete $INSTDIR\Lang\va.txt @@ -442,7 +507,9 @@ Section "Uninstall" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\7-Zip" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe" + !ifndef WIN64 DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\App Paths\7zFMn.exe" + !endif DeleteRegKey HKLM "Software\7-Zip" DeleteRegKey HKCU "Software\7-Zip" diff --git a/DOC/Methods.txt b/DOC/Methods.txt index 593e911e..34e1a5a9 100755 --- a/DOC/Methods.txt +++ b/DOC/Methods.txt @@ -1,5 +1,5 @@ -Compression method IDs (4.16 beta) ----------------------------------- +Compression method IDs (4.27) +----------------------------- Each compression method in 7z has unique binary value (ID). The length of ID in bytes is arbitrary but it can not exceed 15 bytes. @@ -59,9 +59,10 @@ List of defined IDs 04 - Arj 01 - Arj (1,2,3) 02 - Arj 4 - 05 - Lzh - - 07 - Reserved + 05 - Z + 06 - Lzh + 07 - Reserved for 7z + 08 - Cab 06 - Crypto diff --git a/DOC/history.txt b/DOC/history.txt index 3f340525..3944a491 100755 --- a/DOC/history.txt +++ b/DOC/history.txt @@ -1,6 +1,14 @@ Sources history of the 7-Zip ---------------------------- + Version 4.27 2005-09-21 + -------------------------------------- + - Some GUIDs/interfaces were changed. + IStream.h: + ISequentialInStream::Read now works as old ReadPart + ISequentialOutStream::Write now works as old WritePart + + Version 4.26 beta 2005-08-05 -------------------------------------- - MyAlloc(0)/BigAlloc(0) now return 0 diff --git a/DOC/lzma.txt b/DOC/lzma.txt index b7816774..61119a27 100755 --- a/DOC/lzma.txt +++ b/DOC/lzma.txt @@ -1,7 +1,7 @@ -LZMA SDK 4.26 +LZMA SDK 4.27 ------------- -LZMA SDK 4.26 Copyright (C) 1999-2005 Igor Pavlov +LZMA SDK 4.27 Copyright (C) 1999-2005 Igor Pavlov LZMA SDK provides developers with documentation, source code, and sample code necessary to write software that uses LZMA compression. diff --git a/DOC/readme.txt b/DOC/readme.txt index 3c883eca..72de51d2 100755 --- a/DOC/readme.txt +++ b/DOC/readme.txt @@ -1,4 +1,4 @@ -7-Zip 4.25 Sources +7-Zip 4.27 Sources ------------------ 7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP. @@ -9,6 +9,27 @@ License Info ------------ +Most of 7-Zip source code is under GNU LGPL. + +Files in folders + 7zip/Compress/Rar20 + 7zip/Compress/Rar29 + 7zip/Compress/Rar29/Original +are licensed under "unRAR license + GNU LGPL" license. +Source code files in all other folders of this package are under GNU LGPL. + +"unRAR license + GNU LGPL" means that you must follow +GNU LGPL in all aspects while it is in agreement +with unRAR license. But you can not break unRAR license rules. +It means that unRAR license is main license in that pair. + +You can find unRAR license in file unrarLicense.txt +You can find GNU LGPL license in file copying.txt + + +GNU LGPL information: +--------------------- + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -24,6 +45,31 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +unRAR license + GNU LGPL Notes +------------------------------ + +Please check main restriction from unRar license: + + 2. The unRAR sources may be used in any software to handle RAR + archives without limitations free of charge, but cannot be used + to re-create the RAR compression algorithm, which is proprietary. + Distribution of modified unRAR sources in separate form or as a + part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + +In brief it means: +1) You can compile and use compiled files under GNU LGPL rules, since + unRAR license almost has no restrictions for compiled files. + You can link these compiled files to LGPL programs. +2) You can fix bugs in source code and use compiled fixed version. +3) You can not use unRAR sources to re-create the RAR compression algorithm. + + +7zip\Compress\Rar29\Original folder contains files that are modified +versions of original unRAR source code files. + + License notes ------------- @@ -37,7 +83,7 @@ http://www.7-zip.org/support.html Also this package contains files from LZMA SDK you can download LZMA SDK from this page: http://www.7-zip.org/sdk.html -read about license for LZMA SDk in file +read about addtional licenses for LZMA SDK in file DOC/lzma.txt @@ -58,18 +104,15 @@ Tools / Options / Directories - Library files -Also if you want to compile Original BZip2 code you must -download BZip source to folder -7zip/Compress/BZip2Original/Original -You can find BZip2 sources from that page: -http://sources.redhat.com/bzip2/index.html +To compile 7-Zip for AMD64 and IA64 you need: + Windows Server 2003 SP1 Platform SDK from microsoft.com Compiling under Unix/Linux -------------------------- -If sizeof(wchar_t) == 4 in your compiler, -you must use only 2 low bytes of wchar_t. +Check this site for Posix/Linux version: +http://sourceforge.net/projects/p7zip/ Notes: @@ -94,6 +137,7 @@ DOC Documentation --- 7zFormat.txt - 7z format description copying.txt - GNU LGPL license + unRarLicense.txt - License for unRAR part of source code history.txt - Sources history Methods.txt - Compression method IDs readme.txt - Readme file diff --git a/DOC/unRarLicense.txt b/DOC/unRarLicense.txt new file mode 100755 index 00000000..5f78b728 --- /dev/null +++ b/DOC/unRarLicense.txt @@ -0,0 +1,41 @@ + ****** ***** ****** unRAR - free utility for RAR archives + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ****** ******* ****** License for use and distribution of + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ** ** ** ** ** ** FREE portable version + ~~~~~~~~~~~~~~~~~~~~~ + + The source code of unRAR utility is freeware. This means: + + 1. All copyrights to RAR and the utility unRAR are exclusively + owned by the author - Alexander Roshal. + + 2. The unRAR sources may be used in any software to handle RAR + archives without limitations free of charge, but cannot be used + to re-create the RAR compression algorithm, which is proprietary. + Distribution of modified unRAR sources in separate form or as a + part of other software is permitted, provided that it is clearly + stated in the documentation and source comments that the code may + not be used to develop a RAR (WinRAR) compatible archiver. + + 3. The unRAR utility may be freely distributed. No person or company + may charge a fee for the distribution of unRAR without written + permission from the copyright holder. + + 4. THE RAR ARCHIVER AND THE UNRAR UTILITY ARE DISTRIBUTED "AS IS". + NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT + YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, + DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING + OR MISUSING THIS SOFTWARE. + + 5. Installing and using the unRAR utility signifies acceptance of + these terms and conditions of the license. + + 6. If you don't agree with terms of the license you must remove + unRAR files from your storage devices and cease to use the + utility. + + Thank you for your interest in RAR and unRAR. + + + Alexander L. Roshal
\ No newline at end of file diff --git a/Windows/Control/ListView.h b/Windows/Control/ListView.h index 49a1e0ea..845a8945 100755 --- a/Windows/Control/ListView.h +++ b/Windows/Control/ListView.h @@ -38,7 +38,7 @@ public: int GetItemCount() const { return ListView_GetItemCount(_window); } - INT GetSelectionMark() + INT GetSelectionMark() const { return ListView_GetSelectionMark(_window); } void SetItemCount(int numItems) @@ -63,7 +63,7 @@ public: void SetItemState(int index, UINT state, UINT mask) { ListView_SetItemState(_window, index, state, mask); } - UINT GetItemState(int index, UINT mask) + UINT GetItemState(int index, UINT mask) const { return ListView_GetItemState(_window, index, mask); } bool GetColumn(int columnIndex, LVCOLUMN* columnInfo) const diff --git a/Windows/FileIO.cpp b/Windows/FileIO.cpp index 67a2397b..f265f537 100755 --- a/Windows/FileIO.cpp +++ b/Windows/FileIO.cpp @@ -146,10 +146,40 @@ bool CInFile::Open(LPCWSTR fileName) } #endif +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). + +static UINT32 kChunkSizeMax = (1 << 24); + +bool CInFile::ReadPart(void *data, UINT32 size, UINT32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UINT32)processedLoc; + return res; +} + bool CInFile::Read(void *data, UINT32 size, UINT32 &processedSize) { - return BOOLToBool(::ReadFile(_handle, data, size, - (DWORD *)&processedSize, NULL)); + processedSize = 0; + do + { + UINT32 processedLoc = 0; + bool res = ReadPart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (void *)((unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; } ///////////////////////// @@ -210,10 +240,33 @@ bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime) return SetTime(NULL, NULL, lastWriteTime); } +bool COutFile::WritePart(const void *data, UINT32 size, UINT32 &processedSize) +{ + if (size > kChunkSizeMax) + size = kChunkSizeMax; + DWORD processedLoc = 0; + bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL)); + processedSize = (UINT32)processedLoc; + return res; +} + bool COutFile::Write(const void *data, UINT32 size, UINT32 &processedSize) { - return BOOLToBool(::WriteFile(_handle, data, size, - (DWORD *)&processedSize, NULL)); + processedSize = 0; + do + { + UINT32 processedLoc = 0; + bool res = WritePart(data, size, processedLoc); + processedSize += processedLoc; + if (!res) + return false; + if (processedLoc == 0) + return true; + data = (const void *)((const unsigned char *)data + processedLoc); + size -= processedLoc; + } + while (size > 0); + return true; } bool COutFile::SetEndOfFile() diff --git a/Windows/FileIO.h b/Windows/FileIO.h index 36f69df7..b4d8361d 100755 --- a/Windows/FileIO.h +++ b/Windows/FileIO.h @@ -60,6 +60,7 @@ public: DWORD creationDisposition, DWORD flagsAndAttributes); bool Open(LPCWSTR fileName); #endif + bool ReadPart(void *data, UINT32 size, UINT32 &processedSize); bool Read(void *data, UINT32 size, UINT32 &processedSize); }; @@ -90,6 +91,7 @@ public: bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime); bool SetLastWriteTime(const FILETIME *lastWriteTime); + bool WritePart(const void *data, UINT32 size, UINT32 &processedSize); bool Write(const void *data, UINT32 size, UINT32 &processedSize); bool SetEndOfFile(); bool SetLength(UINT64 length); diff --git a/Windows/PropVariant.cpp b/Windows/PropVariant.cpp index 82d71457..48321bc2 100755 --- a/Windows/PropVariant.cpp +++ b/Windows/PropVariant.cpp @@ -142,7 +142,8 @@ CPropVariant& CPropVariant::operator=(Int16 value) return *this; } -CPropVariant& CPropVariant::operator=(long value) +/* +CPropVariant& CPropVariant::operator=(LONG value) { if (vt != VT_I4) { @@ -152,6 +153,7 @@ CPropVariant& CPropVariant::operator=(long value) lVal = value; return *this; } +*/ static HRESULT MyPropVariantClear(PROPVARIANT *propVariant) { diff --git a/Windows/PropVariant.h b/Windows/PropVariant.h index 548ed6fe..71035073 100755 --- a/Windows/PropVariant.h +++ b/Windows/PropVariant.h @@ -25,7 +25,7 @@ public: CPropVariant(Int32 value) { vt = VT_I4; lVal = value; } CPropVariant(Byte value) { vt = VT_UI1; bVal = value; } CPropVariant(Int16 value) { vt = VT_I2; iVal = value; } - CPropVariant(long value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; } + // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; } CPropVariant& operator=(const CPropVariant& varSrc); CPropVariant& operator=(const PROPVARIANT& varSrc); @@ -39,7 +39,7 @@ public: CPropVariant& operator=(Int32 value); CPropVariant& operator=(Byte value); CPropVariant& operator=(Int16 value); - CPropVariant& operator=(long value); + // CPropVariant& operator=(LONG value); HRESULT Clear(); HRESULT Copy(const PROPVARIANT* pSrc); diff --git a/Windows/PropVariantConversions.cpp b/Windows/PropVariantConversions.cpp index f7743d6e..073eb069 100755 --- a/Windows/PropVariantConversions.cpp +++ b/Windows/PropVariantConversions.cpp @@ -6,14 +6,11 @@ #include "PropVariantConversions.h" -#include "Windows/NationalTime.h" #include "Windows/Defs.h" #include "Common/StringConvert.h" #include "Common/IntToString.h" -using namespace NWindows; - static UString ConvertUInt64ToString(UInt64 value) { wchar_t buffer[32]; |