diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/Chm')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.cpp | 721 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.h | 29 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.cpp | 24 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.h | 28 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.cpp | 937 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.h | 244 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmRegister.cpp | 13 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Chm/StdAfx.h | 8 |
8 files changed, 0 insertions, 2004 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.cpp deleted file mode 100644 index a9e334b03..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.cpp +++ /dev/null @@ -1,721 +0,0 @@ -// ChmHandler.cpp - -#include "StdAfx.h" - -#include "Common/ComTry.h" -#include "Common/Defs.h" -#include "Common/StringConvert.h" -#include "Common/UTFConvert.h" - -#include "Windows/PropVariant.h" -#include "Windows/Time.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "../../Compress/CopyCoder.h" -#include "../../Compress/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 -}; - -#endif - -STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidMethod, VT_BSTR}, - { NULL, kpidBlock, VT_UI4} - - #ifdef _CHM_DETAILS - , - { L"Section", kpidSection, VT_UI4}, - { NULL, kpidOffset, VT_UI4} - #endif -}; - -STATPROPSTG kArcProps[] = -{ - { NULL, kpidNumBlocks, VT_UI8} -}; - -IMP_IInArchive_Props - -IMP_IInArchive_ArcProps_NO -/* -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - switch(propID) - { - case kpidNumBlocks: - { - UInt64 numBlocks = 0; - for (int i = 0; i < m_Database.Sections.Size(); i++) - { - const CSectionInfo &s = m_Database.Sections[i]; - for (int j = 0; j < s.Methods.Size(); j++) - { - const CMethodInfo &m = s.Methods[j]; - if (m.IsLzx()) - numBlocks += m.LzxInfo.ResetTable.GetNumBlocks(); - } - } - prop = numBlocks; - break; - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} -*/ - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - if (m_Database.NewFormat) - { - switch(propID) - { - case kpidSize: - prop = (UInt64)m_Database.NewFormatString.Length(); - break; - } - prop.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); - } - prop = NItemName::GetOSName2(us); - } - break; - } - case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; - case kpidMethod: - { - if (!item.IsDir()) - if (item.Section == 0) - prop = L"Copy"; - else if (item.Section < m_Database.Sections.Size()) - prop = m_Database.Sections[(int)item.Section].GetMethodName(); - break; - } - case kpidBlock: - if (m_Database.LowLevel) - prop = item.Section; - else if (item.Section != 0) - prop = m_Database.GetFolder(index); - break; - - #ifdef _CHM_DETAILS - - case kpidSection: prop = (UInt32)item.Section; break; - case kpidOffset: prop = (UInt32)item.Offset; break; - - #endif - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CProgressImp: public CProgressVirt -{ - CMyComPtr<IArchiveOpenCallback> _callback; -public: - STDMETHOD(SetTotal)(const UInt64 *numFiles); - STDMETHOD(SetCompleted)(const UInt64 *numFiles); - CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}; -}; - -STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles) -{ - if (_callback) - return _callback->SetCompleted(numFiles, NULL); - return S_OK; -} - -STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles) -{ - if (_callback) - return _callback->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; - // CProgressImp progressImp(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_Database.Clear(); - 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(UInt64 maxSize); -}; - -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 = 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(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 ? - NExtract::NOperationResult::kOK: - 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(UInt64 maxSize) -{ - const UInt32 kBufferSize = (1 << 10); - Byte buffer[kBufferSize]; - for (int i = 0; i < kBufferSize; i++) - buffer[i] = 0; - if (maxSize > m_FolderSize) - maxSize = m_FolderSize; - while (m_PosInFolder < maxSize) - { - UInt32 size = (UInt32)MyMin(maxSize - m_PosInFolder, (UInt64)kBufferSize); - UInt32 processedSizeLocal = 0; - RINOK(Write2(buffer, size, &processedSizeLocal, false)); - if (processedSizeLocal == 0) - return S_OK; - } - return S_OK; -} - - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testModeSpec, 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 = (testModeSpec != 0); - - UInt64 currentTotalSize = 0; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - UInt32 i; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(m_Stream); - - if (m_Database.LowLevel) - { - 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) - { - currentItemSize = 0; - lps->InSize = currentTotalSize; // Change it - lps->OutSize = currentTotalSize; - - RINOK(lps->SetCur()); - CMyComPtr<ISequentialOutStream> realOutStream; - Int32 askMode= testMode ? - NExtract::NAskMode::kTest : - 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)); - } - RINOK(extractCallback->SetOperationResult(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(NExtract::NOperationResult::kUnSupportedMethod)); - continue; - } - - if (testMode) - { - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - 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.IsDir() || item.Size == 0) - continue; - if (sectionIndex == 0) - { - currentTotalSize += item.Size; - continue; - } - const CSectionInfo §ion = m_Database.Sections[(int)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 ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - if (item.IsDir()) - { - CMyComPtr<ISequentialOutStream> realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - lps->InSize = currentTotalSize; // Change it - lps->OutSize = currentTotalSize; - - if (item.Size == 0 || sectionIndex == 0) - { - CMyComPtr<ISequentialOutStream> realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - Int32 opRes = NExtract::NOperationResult::kOK; - if (!testMode && item.Size != 0) - { - RINOK(m_Stream->Seek(m_Database.ContentOffset + item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(item.Size); - RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress)); - if (copyCoderSpec->TotalSize != item.Size) - opRes = NExtract::NOperationResult::kDataError; - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - currentTotalSize += item.Size; - continue; - } - - const CSectionInfo §ion = m_Database.Sections[(int)sectionIndex]; - - if (!section.IsLzx()) - { - CMyComPtr<ISequentialOutStream> realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(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 (;; 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 offset = rt.ResetOffsets[(int)bCur]; - UInt64 compressedSize; - rt.GetCompressedSizeOfBlock(bCur, compressedSize); - UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection; - if (rem > rt.BlockSize) - rem = rt.BlockSize; - RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL)); - streamSpec->SetStream(m_Stream); - streamSpec->Init(compressedSize); - lzxDecoderSpec->SetKeepHistory(b > 0); - HRESULT res = lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL); - if (res != S_OK) - { - if (res != S_FALSE) - return res; - throw 1; - } - } - } - catch(...) - { - RINOK(chmFolderOutStream->FlushCorrupted(unPackSize)); - } - currentTotalSize += folderSize; - if (folderIndex == lastFolderIndex) - break; - extractStatuses.Clear(); - } - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = m_Database.NewFormat ? 1: - (m_Database.LowLevel ? - m_Database.Items.Size(): - m_Database.Indices.Size()); - return S_OK; -} - -}} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.h b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.h deleted file mode 100644 index 440c50f11..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHandler.h +++ /dev/null @@ -1,29 +0,0 @@ -// 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_IMP1(IInArchive) - - INTERFACE_IInArchive(;) - -private: - CFilesDatabase m_Database; - CMyComPtr<IInStream> m_Stream; -}; - -}} - -#endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.cpp deleted file mode 100644 index e8dc9f3e8..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// 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/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.h b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.h deleted file mode 100644 index 9f1bd42b6..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmHeader.h +++ /dev/null @@ -1,28 +0,0 @@ -// 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/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.cpp deleted file mode 100644 index d52b9ba6c..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.cpp +++ /dev/null @@ -1,937 +0,0 @@ -// Archive/ChmIn.cpp - -#include "StdAfx.h" - -#include "Common/IntToString.h" -#include "Common/UTFConvert.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 (char)((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:"; - wchar_t temp[16]; - ConvertUInt32ToString(LzxInfo.GetNumDictBits(), 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::Skip(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) - { - Skip(size); - return; - } - s += c; - } -} - -void CInArchive::ReadUString(int size, UString &s) -{ - s.Empty(); - while(size-- != 0) - { - wchar_t c = ReadUInt16(); - if (c == 0) - { - Skip(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->SetStream(inStream); - streamSpec->Init(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; - for (;;) - { - UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos; - UInt32 offsetLimit = dirChunkSize - quickrefLength; - if (offset > offsetLimit) - return S_FALSE; - if (offset == offsetLimit) - break; - RINOK(ReadDirEntry(database)); - numItems++; - } - Skip(quickrefLength - 2); - if (ReadUInt16() != numItems) - return S_FALSE; - } - else - Skip(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; - for (;;) - { - 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++; - } - Skip(quickrefLength - 2); - if (ReadUInt16() != numItems) - return S_FALSE; - if (numItems > numDirEntries) - return S_FALSE; - numDirEntries -= numItems; - } - else - Skip(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.IsDir(); - bool isDir2 = item2.IsDir(); - 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.IsDir()) - 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 != 1 && - li.ResetInterval != 2 && - li.ResetInterval != 4 && - li.ResetInterval != 8 && - li.ResetInterval != 16 && - li.ResetInterval != 32 && - li.ResetInterval != 64) - return S_FALSE; - if ( - li.WindowSize != 1 && - li.WindowSize != 2 && - li.WindowSize != 4 && - li.WindowSize != 8 && - li.WindowSize != 16 && - li.WindowSize != 32 && - li.WindowSize != 64) - 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; - UInt64 limit = 1 << 18; - if (searchHeaderSizeLimit) - if (limit > *searchHeaderSizeLimit) - limit = *searchHeaderSizeLimit; - - for (;;) - { - 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 (_inBuffer.GetProcessedSize() > limit) - 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/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.h b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.h deleted file mode 100644 index 4719a484d..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmIn.h +++ /dev/null @@ -1,244 +0,0 @@ -// Archive/ChmIn.h - -#ifndef __ARCHIVE_CHM_IN_H -#define __ARCHIVE_CHM_IN_H - -#include "Common/Buffer.h" -#include "Common/MyString.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 IsDir() 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[(int)blockIndex]; - if (blockIndex + numBlocks >= ResetOffsets.Size()) - size = CompressedSize - startPos; - else - size = ResetOffsets[(int)(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[(int)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[(int)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[(int)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 Skip(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/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmRegister.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmRegister.cpp deleted file mode 100644 index e5f38afa4..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/ChmRegister.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// ChmRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "ChmHandler.h" -static IInArchive *CreateArc() { return new NArchive::NChm::CHandler; } - -static CArcInfo g_ArcInfo = - { L"Chm", L"chm chi chq chw hxs hxi hxr hxq hxw lit", 0, 0xE9, { 'I', 'T', 'S', 'F' }, 4, false, CreateArc, 0 }; - -REGISTER_ARC(Chm) diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Chm/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Archive/Chm/StdAfx.h deleted file mode 100644 index e7fb6986d..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Chm/StdAfx.h +++ /dev/null @@ -1,8 +0,0 @@ -// StdAfx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/MyWindows.h" - -#endif |