diff options
author | kh1 <karsten.heimrich@digia.com> | 2013-05-02 15:28:22 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@digia.com> | 2013-05-08 13:01:55 +0200 |
commit | d89674f944c419c9473da688993ee69671f2c295 (patch) | |
tree | 8422461a5b45d97b6d32dfa8e060e69d600210c9 /src/libs/7zip/win/CPP/7zip/Archive/Wim | |
parent | 5ed380ebcf8ef1157f651cbdef8393ccac897ee2 (diff) |
Reset to only use the basic LZMA SDK (Windows).
Change-Id: I8088cc4775f6c5397991f00512354836d614ea4e
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Reviewed-by: Tim Jenssen <tim.jenssen@digia.com>
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/Wim')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/StdAfx.h | 8 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.cpp | 660 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.h | 77 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandlerOut.cpp | 639 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.cpp | 855 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.h | 297 | ||||
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/Wim/WimRegister.cpp | 18 |
7 files changed, 0 insertions, 2554 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/StdAfx.h b/src/libs/7zip/win/CPP/7zip/Archive/Wim/StdAfx.h deleted file mode 100644 index e7fb6986d..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/StdAfx.h +++ /dev/null @@ -1,8 +0,0 @@ -// StdAfx.h - -#ifndef __STDAFX_H -#define __STDAFX_H - -#include "../../../Common/MyWindows.h" - -#endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.cpp deleted file mode 100644 index eaad1e7ca..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.cpp +++ /dev/null @@ -1,660 +0,0 @@ -// WimHandler.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "Common/ComTry.h" -#include "Common/IntToString.h" -#include "Common/StringToInt.h" -#include "Common/UTFConvert.h" - -#include "Windows/PropVariant.h" - -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "WimHandler.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -using namespace NWindows; - -namespace NArchive { -namespace NWim { - -#define WIM_DETAILS - -static STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidIsDir, VT_BOOL}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackSize, VT_UI8}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidATime, VT_FILETIME}, - { NULL, kpidAttrib, VT_UI4}, - { NULL, kpidMethod, VT_BSTR}, - { NULL, kpidShortName, VT_BSTR} - - #ifdef WIM_DETAILS - , { NULL, kpidVolume, VT_UI4} - , { NULL, kpidOffset, VT_UI8} - , { NULL, kpidLinks, VT_UI4} - #endif -}; - -static STATPROPSTG kArcProps[] = -{ - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackSize, VT_UI8}, - { NULL, kpidMethod, VT_BSTR}, - { NULL, kpidCTime, VT_FILETIME}, - { NULL, kpidMTime, VT_FILETIME}, - { NULL, kpidComment, VT_BSTR}, - { NULL, kpidUnpackVer, VT_BSTR}, - { NULL, kpidIsVolume, VT_BOOL}, - { NULL, kpidVolume, VT_UI4}, - { NULL, kpidNumVolumes, VT_UI4} -}; - -static bool ParseNumber64(const AString &s, UInt64 &res) -{ - const char *end; - if (s.Left(2) == "0x") - { - if (s.Length() == 2) - return false; - res = ConvertHexStringToUInt64((const char *)s + 2, &end); - } - else - { - if (s.IsEmpty()) - return false; - res = ConvertStringToUInt64(s, &end); - } - return *end == 0; -} - -static bool ParseNumber32(const AString &s, UInt32 &res) -{ - UInt64 res64; - if (!ParseNumber64(s, res64) || res64 >= ((UInt64)1 << 32)) - return false; - res = (UInt32)res64; - return true; -} - -bool ParseTime(const CXmlItem &item, FILETIME &ft, const char *tag) -{ - int index = item.FindSubTag(tag); - if (index >= 0) - { - const CXmlItem &timeItem = item.SubItems[index]; - UInt32 low = 0, high = 0; - if (ParseNumber32(timeItem.GetSubStringForTag("LOWPART"), low) && - ParseNumber32(timeItem.GetSubStringForTag("HIGHPART"), high)) - { - ft.dwLowDateTime = low; - ft.dwHighDateTime = high; - return true; - } - } - return false; -} - -void CImageInfo::Parse(const CXmlItem &item) -{ - CTimeDefined = ParseTime(item, CTime, "CREATIONTIME"); - MTimeDefined = ParseTime(item, MTime, "LASTMODIFICATIONTIME"); - NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name); - // IndexDefined = ParseNumber32(item.GetPropertyValue("INDEX"), Index); -} - -void CXml::ToUnicode(UString &s) -{ - size_t size = Data.GetCapacity(); - if (size < 2 || (size & 1) != 0 || size > (1 << 24)) - return; - const Byte *p = Data; - if (Get16(p) != 0xFEFF) - return; - wchar_t *chars = s.GetBuffer((int)size / 2); - for (size_t i = 2; i < size; i += 2) - *chars++ = (wchar_t)Get16(p + i); - *chars = 0; - s.ReleaseBuffer(); -} - -void CXml::Parse() -{ - UString s; - ToUnicode(s); - AString utf; - if (!ConvertUnicodeToUTF8(s, utf)) - return; - ::CXml xml; - if (!xml.Parse(utf)) - return; - if (xml.Root.Name != "WIM") - return; - - for (int i = 0; i < xml.Root.SubItems.Size(); i++) - { - const CXmlItem &item = xml.Root.SubItems[i]; - if (item.IsTagged("IMAGE")) - { - CImageInfo imageInfo; - imageInfo.Parse(item); - Images.Add(imageInfo); - } - } -} - -static const char *kMethodLZX = "LZX"; -static const char *kMethodXpress = "XPress"; -static const char *kMethodCopy = "Copy"; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NWindows::NCOM::CPropVariant prop; - - const CImageInfo *image = NULL; - if (_xmls.Size() == 1) - { - const CXml &xml = _xmls[0]; - if (xml.Images.Size() == 1) - image = &xml.Images[0]; - } - - switch(propID) - { - case kpidSize: prop = _db.GetUnpackSize(); break; - case kpidPackSize: prop = _db.GetPackSize(); break; - - case kpidCTime: - if (_xmls.Size() == 1) - { - const CXml &xml = _xmls[0]; - int index = -1; - for (int i = 0; i < xml.Images.Size(); i++) - { - const CImageInfo &image = xml.Images[i]; - if (image.CTimeDefined) - if (index < 0 || ::CompareFileTime(&image.CTime, &xml.Images[index].CTime) < 0) - index = i; - } - if (index >= 0) - prop = xml.Images[index].CTime; - } - break; - - case kpidMTime: - if (_xmls.Size() == 1) - { - const CXml &xml = _xmls[0]; - int index = -1; - for (int i = 0; i < xml.Images.Size(); i++) - { - const CImageInfo &image = xml.Images[i]; - if (image.MTimeDefined) - if (index < 0 || ::CompareFileTime(&image.MTime, &xml.Images[index].MTime) > 0) - index = i; - } - if (index >= 0) - prop = xml.Images[index].MTime; - } - break; - - case kpidComment: - if (image != NULL) - { - if (_xmlInComments) - { - UString s; - _xmls[0].ToUnicode(s); - prop = s; - } - else if (image->NameDefined) - prop = image->Name; - } - break; - - case kpidUnpackVer: - { - UInt32 ver1 = _version >> 16; - UInt32 ver2 = (_version >> 8) & 0xFF; - UInt32 ver3 = (_version) & 0xFF; - - char s[16]; - ConvertUInt32ToString(ver1, s); - AString res = s; - res += '.'; - ConvertUInt32ToString(ver2, s); - res += s; - if (ver3 != 0) - { - res += '.'; - ConvertUInt32ToString(ver3, s); - res += s; - } - prop = res; - break; - } - - case kpidIsVolume: - if (_xmls.Size() > 0) - { - UInt16 volIndex = _xmls[0].VolIndex; - if (volIndex < _volumes.Size()) - prop = (_volumes[volIndex].Header.NumParts > 1); - } - break; - case kpidVolume: - if (_xmls.Size() > 0) - { - UInt16 volIndex = _xmls[0].VolIndex; - if (volIndex < _volumes.Size()) - prop = (UInt32)_volumes[volIndex].Header.PartNumber; - } - break; - case kpidNumVolumes: if (_volumes.Size() > 0) prop = (UInt32)(_volumes.Size() - 1); break; - case kpidMethod: - { - bool lzx = false, xpress = false, copy = false; - for (int i = 0; i < _xmls.Size(); i++) - { - const CHeader &header = _volumes[_xmls[i].VolIndex].Header; - if (header.IsCompressed()) - if (header.IsLzxMode()) - lzx = true; - else - xpress = true; - else - copy = true; - } - AString res; - if (lzx) - res = kMethodLZX; - if (xpress) - { - if (!res.IsEmpty()) - res += ' '; - res += kMethodXpress; - } - if (copy) - { - if (!res.IsEmpty()) - res += ' '; - res += kMethodCopy; - } - prop = res; - } - } - 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 (index < (UInt32)_db.SortedItems.Size()) - { - int realIndex = _db.SortedItems[index]; - const CItem &item = _db.Items[realIndex]; - const CStreamInfo *si = NULL; - const CVolume *vol = NULL; - if (item.StreamIndex >= 0) - { - si = &_db.Streams[item.StreamIndex]; - vol = &_volumes[si->PartNumber]; - } - - switch(propID) - { - case kpidPath: - if (item.HasMetadata) - prop = _db.GetItemPath(realIndex); - else - { - char sz[16]; - ConvertUInt32ToString(item.StreamIndex, sz); - AString s = sz; - while (s.Length() < _nameLenForStreams) - s = '0' + s; - /* - if (si->Resource.IsFree()) - prefix = "[Free]"; - */ - s = "[Files]" STRING_PATH_SEPARATOR + s; - prop = s; - } - break; - case kpidShortName: if (item.HasMetadata) prop = item.ShortName; break; - - case kpidIsDir: prop = item.IsDir(); break; - case kpidAttrib: if (item.HasMetadata) prop = item.Attrib; break; - case kpidCTime: if (item.HasMetadata) prop = item.CTime; break; - case kpidATime: if (item.HasMetadata) prop = item.ATime; break; - case kpidMTime: if (item.HasMetadata) prop = item.MTime; break; - case kpidPackSize: prop = si ? si->Resource.PackSize : (UInt64)0; break; - case kpidSize: prop = si ? si->Resource.UnpackSize : (UInt64)0; break; - case kpidMethod: if (si) prop = si->Resource.IsCompressed() ? - (vol->Header.IsLzxMode() ? kMethodLZX : kMethodXpress) : kMethodCopy; break; - #ifdef WIM_DETAILS - case kpidVolume: if (si) prop = (UInt32)si->PartNumber; break; - case kpidOffset: if (si) prop = (UInt64)si->Resource.Offset; break; - case kpidLinks: prop = si ? (UInt32)si->RefCount : (UInt32)0; break; - #endif - } - } - else - { - index -= _db.SortedItems.Size(); - { - switch(propID) - { - case kpidPath: - { - char sz[16]; - ConvertUInt32ToString(_xmls[index].VolIndex, sz); - prop = (AString)"[" + (AString)sz + "].xml"; - break; - } - case kpidIsDir: prop = false; break; - case kpidPackSize: - case kpidSize: prop = (UInt64)_xmls[index].Data.GetCapacity(); break; - case kpidMethod: prop = kMethodCopy; break; - } - } - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -class CVolumeName -{ - // UInt32 _volIndex; - UString _before; - UString _after; -public: - CVolumeName() {}; - - void InitName(const UString &name) - { - // _volIndex = 1; - int dotPos = name.ReverseFind('.'); - if (dotPos < 0) - dotPos = name.Length(); - _before = name.Left(dotPos); - _after = name.Mid(dotPos); - } - - UString GetNextName(UInt32 index) - { - wchar_t s[16]; - ConvertUInt32ToString(index, s); - return _before + (UString)s + _after; - } -}; - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback *openArchiveCallback) -{ - COM_TRY_BEGIN - Close(); - { - CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; - - CVolumeName seqName; - if (openArchiveCallback != NULL) - openArchiveCallback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback); - - UInt32 numVolumes = 1; - int firstVolumeIndex = -1; - for (UInt32 i = 1; i <= numVolumes; i++) - { - CMyComPtr<IInStream> curStream; - if (i != 1) - { - UString fullName = seqName.GetNextName(i); - HRESULT result = openVolumeCallback->GetStream(fullName, &curStream); - if (result == S_FALSE) - continue; - if (result != S_OK) - return result; - if (!curStream) - break; - } - else - curStream = inStream; - CHeader header; - HRESULT res = NWim::ReadHeader(curStream, header); - if (res != S_OK) - { - if (i == 1) - return res; - if (res == S_FALSE) - continue; - return res; - } - _version = header.Version; - _isOldVersion = header.IsOldVersion(); - if (firstVolumeIndex >= 0) - if (!header.AreFromOnArchive(_volumes[firstVolumeIndex].Header)) - break; - if (_volumes.Size() > header.PartNumber && _volumes[header.PartNumber].Stream) - break; - CXml xml; - xml.VolIndex = header.PartNumber; - res = _db.Open(curStream, header, xml.Data, openArchiveCallback); - if (res != S_OK) - { - if (i == 1) - return res; - if (res == S_FALSE) - continue; - return res; - } - - while (_volumes.Size() <= header.PartNumber) - _volumes.Add(CVolume()); - CVolume &volume = _volumes[header.PartNumber]; - volume.Header = header; - volume.Stream = curStream; - - firstVolumeIndex = header.PartNumber; - - bool needAddXml = true; - if (_xmls.Size() != 0) - if (xml.Data == _xmls[0].Data) - needAddXml = false; - if (needAddXml) - { - xml.Parse(); - _xmls.Add(xml); - } - - if (i == 1) - { - if (header.PartNumber != 1) - break; - if (!openVolumeCallback) - break; - numVolumes = header.NumParts; - { - NCOM::CPropVariant prop; - RINOK(openVolumeCallback->GetProperty(kpidName, &prop)); - if (prop.vt != VT_BSTR) - break; - seqName.InitName(prop.bstrVal); - } - } - } - - _db.DetectPathMode(); - RINOK(_db.Sort(_db.SkipRoot)); - - wchar_t sz[16]; - ConvertUInt32ToString(_db.Streams.Size(), sz); - _nameLenForStreams = MyStringLen(sz); - - _xmlInComments = (_xmls.Size() == 1 && !_db.ShowImageNumber); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _db.Clear(); - _volumes.Clear(); - _xmls.Clear(); - _nameLenForStreams = 0; - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)-1); - - if (allFilesMode) - numItems = _db.SortedItems.Size() + _xmls.Size(); - if (numItems == 0) - return S_OK; - - UInt32 i; - UInt64 totalSize = 0; - for (i = 0; i < numItems; i++) - { - UInt32 index = allFilesMode ? i : indices[i]; - if (index < (UInt32)_db.SortedItems.Size()) - { - int streamIndex = _db.Items[_db.SortedItems[index]].StreamIndex; - if (streamIndex >= 0) - { - const CStreamInfo &si = _db.Streams[streamIndex]; - totalSize += si.Resource.UnpackSize; - } - } - else - totalSize += _xmls[index - (UInt32)_db.SortedItems.Size()].Data.GetCapacity(); - } - - RINOK(extractCallback->SetTotal(totalSize)); - - UInt64 currentTotalPacked = 0; - UInt64 currentTotalUnPacked = 0; - UInt64 currentItemUnPacked, currentItemPacked; - - int prevSuccessStreamIndex = -1; - - CUnpacker unpacker; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - for (i = 0; i < numItems; currentTotalUnPacked += currentItemUnPacked, - currentTotalPacked += currentItemPacked) - { - currentItemUnPacked = 0; - currentItemPacked = 0; - - lps->InSize = currentTotalPacked; - lps->OutSize = currentTotalUnPacked; - - RINOK(lps->SetCur()); - UInt32 index = allFilesMode ? i : indices[i]; - i++; - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - - CMyComPtr<ISequentialOutStream> realOutStream; - RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - if (index >= (UInt32)_db.SortedItems.Size()) - { - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - const CByteBuffer &data = _xmls[index - (UInt32)_db.SortedItems.Size()].Data; - currentItemUnPacked = data.GetCapacity(); - if (realOutStream) - { - RINOK(WriteStream(realOutStream, (const Byte *)data, data.GetCapacity())); - realOutStream.Release(); - } - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); - continue; - } - - const CItem &item = _db.Items[_db.SortedItems[index]]; - int streamIndex = item.StreamIndex; - if (streamIndex < 0) - { - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(item.HasStream() ? - NExtract::NOperationResult::kDataError : - NExtract::NOperationResult::kOK)); - continue; - } - - const CStreamInfo &si = _db.Streams[streamIndex]; - currentItemUnPacked = si.Resource.UnpackSize; - currentItemPacked = si.Resource.PackSize; - - if (!testMode && !realOutStream) - continue; - RINOK(extractCallback->PrepareOperation(askMode)); - Int32 opRes = NExtract::NOperationResult::kOK; - if (streamIndex != prevSuccessStreamIndex || realOutStream) - { - Byte digest[20]; - const CVolume &vol = _volumes[si.PartNumber]; - HRESULT res = unpacker.Unpack(vol.Stream, si.Resource, vol.Header.IsLzxMode(), - realOutStream, progress, digest); - if (res == S_OK) - { - if (memcmp(digest, si.Hash, kHashSize) == 0) - prevSuccessStreamIndex = streamIndex; - else - opRes = NExtract::NOperationResult::kCRCError; - } - else if (res == S_FALSE) - opRes = NExtract::NOperationResult::kDataError; - else - return res; - } - realOutStream.Release(); - RINOK(extractCallback->SetOperationResult(opRes)); - } - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _db.SortedItems.Size(); - if (!_xmlInComments) - *numItems += _xmls.Size(); - return S_OK; -} - -}} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.h b/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.h deleted file mode 100644 index aa92069a5..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.h +++ /dev/null @@ -1,77 +0,0 @@ -// WimHandler.h - -#ifndef __ARCHIVE_WIM_HANDLER_H -#define __ARCHIVE_WIM_HANDLER_H - -#include "Common/MyCom.h" -#include "Common/MyXml.h" - -#include "WimIn.h" - -namespace NArchive { -namespace NWim { - -struct CVolume -{ - CHeader Header; - CMyComPtr<IInStream> Stream; -}; - -struct CImageInfo -{ - bool CTimeDefined; - bool MTimeDefined; - bool NameDefined; - // bool IndexDefined; - - FILETIME CTime; - FILETIME MTime; - UString Name; - // UInt32 Index; - - CImageInfo(): CTimeDefined(false), MTimeDefined(false), NameDefined(false) - // , IndexDefined(false) - {} - void Parse(const CXmlItem &item); -}; - -struct CXml -{ - CByteBuffer Data; - UInt16 VolIndex; - CObjectVector<CImageInfo> Images; - - void ToUnicode(UString &s); - void Parse(); -}; - - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CDatabase _db; - UInt32 _version; - bool _isOldVersion; - CObjectVector<CVolume> _volumes; - CObjectVector<CXml> _xmls; - int _nameLenForStreams; - bool _xmlInComments; - -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) -}; - -class COutHandler: - public IOutArchive, - public CMyUnknownImp -{ -public: - MY_UNKNOWN_IMP1(IOutArchive) - INTERFACE_IOutArchive(;) -}; - -}} - -#endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandlerOut.cpp deleted file mode 100644 index 50b879e79..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandlerOut.cpp +++ /dev/null @@ -1,639 +0,0 @@ -// WimHandlerOut.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "Common/ComTry.h" -#include "Common/IntToString.h" - -#include "Windows/PropVariant.h" -#include "Windows/Time.h" - -#include "../../Common/LimitedStreams.h" -#include "../../Common/ProgressUtils.h" -#include "../../Common/StreamUtils.h" - -#include "../../Crypto/RandGen.h" -#include "../../Crypto/Sha1.h" - -#include "WimHandler.h" - -using namespace NWindows; - -namespace NArchive { -namespace NWim { - -struct CSha1Hash -{ - Byte Hash[kHashSize]; -}; - -struct CHashList -{ - CRecordVector<CSha1Hash> Digests; - CIntVector Sorted; - - int AddUnique(const CSha1Hash &h); -}; - -int CHashList::AddUnique(const CSha1Hash &h) -{ - int left = 0, right = Sorted.Size(); - while (left != right) - { - int mid = (left + right) / 2; - int index = Sorted[mid]; - UInt32 i; - const Byte *hash2 = Digests[index].Hash; - for (i = 0; i < kHashSize; i++) - if (h.Hash[i] != hash2[i]) - break; - if (i == kHashSize) - return index; - if (h.Hash[i] < hash2[i]) - right = mid; - else - left = mid + 1; - } - Sorted.Insert(left, Digests.Add(h)); - return -1; -} - -struct CUpdateItem -{ - UString Name; - UInt64 Size; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - UInt32 Attrib; - bool IsDir; - int HashIndex; - - CUpdateItem(): HashIndex(-1) {} -}; - -struct CDir -{ - int Index; - UString Name; - CObjectVector<CDir> Dirs; - CIntVector Files; - - CDir(): Index(-1) {} - bool IsLeaf() const { return Index >= 0; } - UInt64 GetNumDirs() const; - UInt64 GetNumFiles() const; - CDir* AddDir(CObjectVector<CUpdateItem> &items, const UString &name, int index); -}; - -UInt64 CDir::GetNumDirs() const -{ - UInt64 num = Dirs.Size(); - for (int i = 0; i < Dirs.Size(); i++) - num += Dirs[i].GetNumDirs(); - return num; -} - -UInt64 CDir::GetNumFiles() const -{ - UInt64 num = Files.Size(); - for (int i = 0; i < Dirs.Size(); i++) - num += Dirs[i].GetNumFiles(); - return num; -} - -CDir* CDir::AddDir(CObjectVector<CUpdateItem> &items, const UString &name, int index) -{ - int left = 0, right = Dirs.Size(); - while (left != right) - { - int mid = (left + right) / 2; - CDir &d = Dirs[mid]; - int compare = name.CompareNoCase(d.IsLeaf() ? items[Dirs[mid].Index].Name : d.Name); - if (compare == 0) - { - if (index >= 0) - d.Index = index; - return &d; - } - if (compare < 0) - right = mid; - else - left = mid + 1; - } - Dirs.Insert(left, CDir()); - CDir &d = Dirs[left]; - d.Index = index; - if (index < 0) - d.Name = name; - return &d; -} - - -STDMETHODIMP COutHandler::GetFileTimeType(UInt32 *type) -{ - *type = NFileTimeType::kWindows; - return S_OK; -} - -static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propID, FILETIME &ft) -{ - ft.dwLowDateTime = ft.dwHighDateTime = 0; - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(index, propID, &prop)); - if (prop.vt == VT_FILETIME) - ft = prop.filetime; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - return S_OK; -} - -#define Set16(p, d) SetUi16(p, d) -#define Set32(p, d) SetUi32(p, d) -#define Set64(p, d) SetUi64(p, d) - -void CResource::WriteTo(Byte *p) const -{ - Set64(p, PackSize); - p[7] = Flags; - Set64(p + 8, Offset); - Set64(p + 16, UnpackSize); -} - -void CHeader::WriteTo(Byte *p) const -{ - memcpy(p, kSignature, kSignatureSize); - Set32(p + 8, kHeaderSizeMax); - Set32(p + 0xC, Version); - Set32(p + 0x10, Flags); - Set32(p + 0x14, ChunkSize); - memcpy(p + 0x18, Guid, 16); - Set16(p + 0x28, PartNumber); - Set16(p + 0x2A, NumParts); - Set32(p + 0x2C, NumImages); - OffsetResource.WriteTo(p + 0x30); - XmlResource.WriteTo(p + 0x48); - MetadataResource.WriteTo(p + 0x60); - IntegrityResource.WriteTo(p + 0x7C); - Set32(p + 0x78, BootIndex); - memset(p + 0x94, 0, 60); -} - -void CStreamInfo::WriteTo(Byte *p) const -{ - Resource.WriteTo(p); - Set16(p + 0x18, PartNumber); - Set32(p + 0x1A, RefCount); - memcpy(p + 0x1E, Hash, kHashSize); -} - -class CInStreamWithSha1: - public ISequentialInStream, - public CMyUnknownImp -{ - CMyComPtr<ISequentialInStream> _stream; - UInt64 _size; - NCrypto::NSha1::CContext _sha; -public: - MY_UNKNOWN_IMP1(IInStream) - STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); - - void SetStream(ISequentialInStream *stream) { _stream = stream; } - void Init() - { - _size = 0; - _sha.Init(); - } - void ReleaseStream() { _stream.Release(); } - UInt64 GetSize() const { return _size; } - void Final(Byte *digest) { _sha.Final(digest); } -}; - -STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize) -{ - UInt32 realProcessedSize; - HRESULT result = _stream->Read(data, size, &realProcessedSize); - _size += realProcessedSize; - _sha.Update((const Byte *)data, realProcessedSize); - if (processedSize != NULL) - *processedSize = realProcessedSize; - return result; -} - -static void SetFileTimeToMem(Byte *p, const FILETIME &ft) -{ - Set32(p, ft.dwLowDateTime); - Set32(p + 4, ft.dwHighDateTime); -} - -static size_t WriteItem(const CUpdateItem &item, Byte *p, const Byte *hash) -{ - int fileNameLen = item.Name.Length() * 2; - int fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2); - - size_t totalLen = ((kDirRecordSize + fileNameLen2 + 6) & ~7); - if (p) - { - memset(p, 0, totalLen); - Set64(p, totalLen); - Set64(p + 8, item.Attrib); - Set32(p + 0xC, (UInt32)(Int32)-1); // item.SecurityId - // Set64(p + 0x10, 0); // subdirOffset - SetFileTimeToMem(p + 0x28, item.CTime); - SetFileTimeToMem(p + 0x30, item.ATime); - SetFileTimeToMem(p + 0x38, item.MTime); - if (hash) - memcpy(p + 0x40, hash, kHashSize); - /* - else - memset(p + 0x40, 0, kHashSize); - */ - // Set16(p + 98, 0); // shortNameLen - Set16(p + 100, (UInt16)fileNameLen); - for (int i = 0; i * 2 < fileNameLen; i++) - Set16(p + kDirRecordSize + i * 2, item.Name[i]); - } - return totalLen; -} - -static void WriteTree(const CDir &tree, CRecordVector<CSha1Hash> &digests, - CUpdateItem &defaultDirItem, - CObjectVector<CUpdateItem> &updateItems, Byte *dest, size_t &pos) -{ - int i; - for (i = 0; i < tree.Files.Size(); i++) - { - const CUpdateItem &ui = updateItems[tree.Files[i]]; - pos += WriteItem(ui, dest ? dest + pos : NULL, - ui.HashIndex >= 0 ? digests[ui.HashIndex].Hash : NULL); - } - - size_t posStart = pos; - for (i = 0; i < tree.Dirs.Size(); i++) - { - const CDir &subfolder = tree.Dirs[i]; - CUpdateItem *item = &defaultDirItem; - if (subfolder.IsLeaf()) - item = &updateItems[subfolder.Index]; - else - defaultDirItem.Name = subfolder.Name; - pos += WriteItem(*item, NULL, NULL); - } - - if (dest) - Set64(dest + pos, 0); - - pos += 8; - - for (i = 0; i < tree.Dirs.Size(); i++) - { - const CDir &subfolder = tree.Dirs[i]; - if (dest) - { - CUpdateItem *item = &defaultDirItem; - if (subfolder.IsLeaf()) - item = &updateItems[subfolder.Index]; - else - defaultDirItem.Name = subfolder.Name; - size_t len = WriteItem(*item, dest + posStart, NULL); - Set64(dest + posStart + 0x10, pos); - posStart += len; - } - WriteTree(subfolder, digests, defaultDirItem, updateItems, dest, pos); - } -} - -static void AddTag(AString &s, const char *name, const AString &value) -{ - s += "<"; - s += name; - s += ">"; - s += value; - s += "</"; - s += name; - s += ">"; -} - -static void AddTagUInt64(AString &s, const char *name, UInt64 value) -{ - char temp[32]; - ConvertUInt64ToString(value, temp); - AddTag(s, name, temp); -} - -static AString TimeToXml(FILETIME &ft) -{ - AString res; - char temp[16] = { '0', 'x' }; - ConvertUInt32ToHexWithZeros(ft.dwHighDateTime, temp + 2); - AddTag(res, "HIGHPART", temp); - ConvertUInt32ToHexWithZeros(ft.dwLowDateTime, temp + 2); - AddTag(res, "LOWPART", temp); - return res; -} - -void CHeader::SetDefaultFields(bool useLZX) -{ - Version = kWimVersion; - Flags = NHeaderFlags::kRpFix; - ChunkSize = 0; - if (useLZX) - { - Flags |= NHeaderFlags::kCompression | NHeaderFlags::kLZX; - ChunkSize = kChunkSize; - } - g_RandomGenerator.Generate(Guid, 16); - PartNumber = 1; - NumParts = 1; - NumImages = 1; - BootIndex = 0; - OffsetResource.Clear(); - XmlResource.Clear(); - MetadataResource.Clear(); - IntegrityResource.Clear(); -} - -static HRESULT UpdateArchive(ISequentialOutStream *seqOutStream, - CDir &rootFolder, - CObjectVector<CUpdateItem> &updateItems, - IArchiveUpdateCallback *callback) -{ - CMyComPtr<IOutStream> outStream; - RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream)); - if (!outStream) - return E_NOTIMPL; - - UInt64 complexity = 0; - - int i; - for (i = 0; i < updateItems.Size(); i++) - complexity += updateItems[i].Size; - - RINOK(callback->SetTotal(complexity)); - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; - CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(callback, true); - - complexity = 0; - - bool useCompression = false; - - CHeader header; - header.SetDefaultFields(useCompression); - Byte buf[kHeaderSizeMax]; - header.WriteTo(buf); - RINOK(WriteStream(outStream, buf, kHeaderSizeMax)); - - CHashList hashes; - CObjectVector<CStreamInfo> streams; - - UInt64 curPos = kHeaderSizeMax; - UInt64 unpackTotalSize = 0; - for (i = 0; i < updateItems.Size(); i++) - { - lps->InSize = lps->OutSize = complexity; - RINOK(lps->SetCur()); - - CUpdateItem &ui = updateItems[i]; - if (ui.IsDir || ui.Size == 0) - continue; - - CInStreamWithSha1 *inShaStreamSpec = new CInStreamWithSha1; - CMyComPtr<ISequentialInStream> inShaStream = inShaStreamSpec; - - { - CMyComPtr<ISequentialInStream> fileInStream; - HRESULT res = callback->GetStream(i, &fileInStream); - if (res != S_FALSE) - { - RINOK(res); - inShaStreamSpec->SetStream(fileInStream); - fileInStream.Release(); - inShaStreamSpec->Init(); - UInt64 offsetBlockSize = 0; - if (useCompression) - { - for (UInt64 t = kChunkSize; t < ui.Size; t += kChunkSize) - { - Byte buf[8]; - SetUi32(buf, (UInt32)t); - RINOK(WriteStream(outStream, buf, 4)); - offsetBlockSize += 4; - } - } - - RINOK(copyCoder->Code(inShaStream, outStream, NULL, NULL, progress)); - ui.Size = copyCoderSpec->TotalSize; - - CSha1Hash hash; - unpackTotalSize += ui.Size; - UInt64 packSize = offsetBlockSize + ui.Size; - inShaStreamSpec->Final(hash.Hash); - int index = hashes.AddUnique(hash); - if (index >= 0) - { - ui.HashIndex = index; - streams[index].RefCount++; - outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); - outStream->SetSize(curPos); - } - else - { - ui.HashIndex = hashes.Digests.Size() - 1; - CStreamInfo s; - s.Resource.PackSize = packSize; - s.Resource.Offset = curPos; - s.Resource.UnpackSize = ui.Size; - s.Resource.Flags = 0; - if (useCompression) - s.Resource.Flags = NResourceFlags::Compressed; - s.PartNumber = 1; - s.RefCount = 1; - memcpy(s.Hash, hash.Hash, kHashSize); - streams.Add(s); - curPos += packSize; - } - } - fileInStream.Release(); - complexity += ui.Size; - RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); - } - } - - - CUpdateItem ri; - FILETIME ft; - NTime::GetCurUtcFileTime(ft); - ri.MTime = ri.ATime = ri.CTime = ft; - ri.Attrib = FILE_ATTRIBUTE_DIRECTORY; - - const UInt32 kSecuritySize = 8; - size_t pos = kSecuritySize; - WriteTree(rootFolder, hashes.Digests, ri, updateItems, NULL, pos); - - CByteBuffer meta; - meta.SetCapacity(pos); - - // we can write 0 here only if there is no security data, imageX does it, - // but some programs expect size = 8 - Set32((Byte *)meta, 8); // size of security data - Set32((Byte *)meta + 4, 0); // num security entries - - pos = kSecuritySize; - WriteTree(rootFolder, hashes.Digests, ri, updateItems, (Byte *)meta, pos); - - { - NCrypto::NSha1::CContext sha; - sha.Init(); - sha.Update((const Byte *)meta, pos); - CSha1Hash digest; - sha.Final(digest.Hash); - - CStreamInfo s; - s.Resource.PackSize = pos; - s.Resource.Offset = curPos; - s.Resource.UnpackSize = pos; - s.Resource.Flags = NResourceFlags::kMetadata; - s.PartNumber = 1; - s.RefCount = 1; - memcpy(s.Hash, digest.Hash, kHashSize); - streams.Add(s); - RINOK(WriteStream(outStream, (const Byte *)meta, pos)); - meta.Free(); - curPos += pos; - } - - - header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize; - header.OffsetResource.Offset = curPos; - header.OffsetResource.Flags = NResourceFlags::kMetadata; - - for (i = 0; i < streams.Size(); i++) - { - Byte buf[kStreamInfoSize]; - streams[i].WriteTo(buf); - RINOK(WriteStream(outStream, buf, kStreamInfoSize)); - curPos += kStreamInfoSize; - } - - AString xml = "<WIM>"; - AddTagUInt64(xml, "TOTALBYTES", curPos); - xml += "<IMAGE INDEX=\"1\"><NAME>1</NAME>"; - AddTagUInt64(xml, "DIRCOUNT", rootFolder.GetNumDirs()); - AddTagUInt64(xml, "FILECOUNT", rootFolder.GetNumFiles()); - AddTagUInt64(xml, "TOTALBYTES", unpackTotalSize); - NTime::GetCurUtcFileTime(ft); - AddTag(xml, "CREATIONTIME", TimeToXml(ft)); - AddTag(xml, "LASTMODIFICATIONTIME", TimeToXml(ft)); - xml += "</IMAGE></WIM>"; - - size_t xmlSize = (xml.Length() + 1) * 2; - meta.SetCapacity(xmlSize); - Set16((Byte *)meta, 0xFEFF); - for (i = 0; i < xml.Length(); i++) - Set16((Byte *)meta + 2 + i * 2, xml[i]); - RINOK(WriteStream(outStream, (const Byte *)meta, xmlSize)); - meta.Free(); - - header.XmlResource.UnpackSize = header.XmlResource.PackSize = xmlSize; - header.XmlResource.Offset = curPos; - header.XmlResource.Flags = NResourceFlags::kMetadata; - - outStream->Seek(0, STREAM_SEEK_SET, NULL); - header.WriteTo(buf); - return WriteStream(outStream, buf, kHeaderSizeMax); -} - -STDMETHODIMP COutHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems, - IArchiveUpdateCallback *callback) -{ - COM_TRY_BEGIN - CObjectVector<CUpdateItem> updateItems; - CDir tree; - tree.Dirs.Add(CDir()); - CDir &rootFolder = tree.Dirs.Back(); - - for (UInt32 i = 0; i < numItems; i++) - { - CUpdateItem ui; - Int32 newData, newProps; - UInt32 indexInArchive; - if (!callback) - return E_FAIL; - RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); - - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidIsDir, &prop)); - if (prop.vt == VT_EMPTY) - ui.IsDir = false; - else if (prop.vt != VT_BOOL) - return E_INVALIDARG; - else - ui.IsDir = (prop.boolVal != VARIANT_FALSE); - } - - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidAttrib, &prop)); - if (prop.vt == VT_EMPTY) - ui.Attrib = (ui.IsDir ? FILE_ATTRIBUTE_DIRECTORY : 0); - else if (prop.vt != VT_UI4) - return E_INVALIDARG; - else - ui.Attrib = prop.ulVal; - } - - RINOK(GetTime(callback, i, kpidCTime, ui.CTime)); - RINOK(GetTime(callback, i, kpidATime, ui.ATime)); - RINOK(GetTime(callback, i, kpidMTime, ui.MTime)); - - { - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidSize, &prop)); - if (prop.vt != VT_UI8) - return E_INVALIDARG; - ui.Size = prop.uhVal.QuadPart; - } - - UString path; - NCOM::CPropVariant prop; - RINOK(callback->GetProperty(i, kpidPath, &prop)); - if (prop.vt == VT_BSTR) - path = prop.bstrVal; - else if (prop.vt != VT_EMPTY) - return E_INVALIDARG; - - CDir *curItem = &rootFolder; - int len = path.Length(); - UString fileName; - for (int j = 0; j < len; j++) - { - wchar_t c = path[j]; - if (c == WCHAR_PATH_SEPARATOR || c == L'/') - { - curItem = curItem->AddDir(updateItems, fileName, -1); - fileName.Empty(); - } - else - fileName += c; - } - - ui.Name = fileName; - updateItems.Add(ui); - if (ui.IsDir) - curItem->AddDir(updateItems, fileName, (int)i); - else - curItem->Files.Add(i); - } - return UpdateArchive(outStream, tree, updateItems, callback); - COM_TRY_END -} - -}} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.cpp deleted file mode 100644 index c210804df..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.cpp +++ /dev/null @@ -1,855 +0,0 @@ -// Archive/WimIn.cpp - -#include "StdAfx.h" - -#include "../../../../C/CpuArch.h" - -#include "Common/IntToString.h" - -#include "../../Common/StreamUtils.h" -#include "../../Common/StreamObjects.h" -#include "../../Common/LimitedStreams.h" - -#include "../Common/OutStreamWithSha1.h" - -#include "WimIn.h" - -#define Get16(p) GetUi16(p) -#define Get32(p) GetUi32(p) -#define Get64(p) GetUi64(p) - -namespace NArchive { -namespace NWim { - -namespace NXpress { - -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(); - } -}; - -HRESULT CDecoder::CodeSpec(UInt32 outSize) -{ - { - Byte levels[kMainTableSize]; - for (unsigned i = 0; i < kMainTableSize; i += 2) - { - Byte b = m_InBitStream.DirectReadByte(); - levels[i] = b & 0xF; - levels[i + 1] = b >> 4; - } - if (!m_MainDecoder.SetCodeLengths(levels)) - return S_FALSE; - } - - while (outSize > 0) - { - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); - if (number < 256) - { - m_OutWindowStream.PutByte((Byte)number); - outSize--; - } - else - { - if (number >= kMainTableSize) - return S_FALSE; - UInt32 posLenSlot = number - 256; - UInt32 posSlot = posLenSlot / kNumLenSlots; - UInt32 len = posLenSlot % kNumLenSlots; - UInt32 distance = (1 << posSlot) - 1 + m_InBitStream.ReadBits(posSlot); - - if (len == kNumLenSlots - 1) - { - len = m_InBitStream.DirectReadByte(); - if (len == 0xFF) - { - len = m_InBitStream.DirectReadByte(); - len |= (UInt32)m_InBitStream.DirectReadByte() << 8; - } - else - len += kNumLenSlots - 1; - } - - len += kMatchMinLen; - UInt32 locLen = (len <= outSize ? len : outSize); - - if (!m_OutWindowStream.CopyBlock(distance, locLen)) - return S_FALSE; - - len -= locLen; - outSize -= locLen; - if (len != 0) - return S_FALSE; - } - } - return S_OK; -} - -const UInt32 kDictSize = (1 << kNumPosSlots); - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize) -{ - if (!m_OutWindowStream.Create(kDictSize) || !m_InBitStream.Create(1 << 16)) - return E_OUTOFMEMORY; - - CDecoderFlusher flusher(this); - - m_InBitStream.SetStream(inStream); - m_OutWindowStream.SetStream(outStream); - m_InBitStream.Init(); - m_OutWindowStream.Init(false); - - RINOK(CodeSpec(outSize)); - - flusher.NeedFlush = false; - return Flush(); -} - -HRESULT CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize) -{ - try { return CodeReal(inStream, outStream, outSize); } - catch(const CInBufferException &e) { return e.ErrorCode; } \ - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -} - -HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, bool lzxMode, - ISequentialOutStream *outStream, ICompressProgressInfo *progress) -{ - RINOK(inStream->Seek(resource.Offset, STREAM_SEEK_SET, NULL)); - - CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream(); - CMyComPtr<ISequentialInStream> limitedStream = limitedStreamSpec; - limitedStreamSpec->SetStream(inStream); - - if (!copyCoder) - { - copyCoderSpec = new NCompress::CCopyCoder; - copyCoder = copyCoderSpec; - } - if (!resource.IsCompressed()) - { - if (resource.PackSize != resource.UnpackSize) - return S_FALSE; - limitedStreamSpec->Init(resource.PackSize); - return copyCoder->Code(limitedStreamSpec, outStream, NULL, NULL, progress); - } - if (resource.UnpackSize == 0) - return S_OK; - UInt64 numChunks = (resource.UnpackSize + kChunkSize - 1) >> kChunkSizeBits; - unsigned entrySize = ((resource.UnpackSize > (UInt64)1 << 32) ? 8 : 4); - UInt64 sizesBufSize64 = entrySize * (numChunks - 1); - size_t sizesBufSize = (size_t)sizesBufSize64; - if (sizesBufSize != sizesBufSize64) - return E_OUTOFMEMORY; - if (sizesBufSize > sizesBuf.GetCapacity()) - { - sizesBuf.Free(); - sizesBuf.SetCapacity(sizesBufSize); - } - RINOK(ReadStream_FALSE(inStream, (Byte *)sizesBuf, sizesBufSize)); - const Byte *p = (const Byte *)sizesBuf; - - if (lzxMode && !lzxDecoder) - { - lzxDecoderSpec = new NCompress::NLzx::CDecoder(true); - lzxDecoder = lzxDecoderSpec; - RINOK(lzxDecoderSpec->SetParams(kChunkSizeBits)); - } - - UInt64 baseOffset = resource.Offset + sizesBufSize64; - UInt64 outProcessed = 0; - for (UInt32 i = 0; i < (UInt32)numChunks; i++) - { - UInt64 offset = 0; - if (i > 0) - { - offset = (entrySize == 4) ? Get32(p): Get64(p); - p += entrySize; - } - UInt64 nextOffset = resource.PackSize - sizesBufSize64; - if (i + 1 < (UInt32)numChunks) - nextOffset = (entrySize == 4) ? Get32(p): Get64(p); - if (nextOffset < offset) - return S_FALSE; - - RINOK(inStream->Seek(baseOffset + offset, STREAM_SEEK_SET, NULL)); - UInt64 inSize = nextOffset - offset; - limitedStreamSpec->Init(inSize); - - if (progress) - { - RINOK(progress->SetRatioInfo(&offset, &outProcessed)); - } - - UInt32 outSize = kChunkSize; - if (outProcessed + outSize > resource.UnpackSize) - outSize = (UInt32)(resource.UnpackSize - outProcessed); - UInt64 outSize64 = outSize; - if (inSize == outSize) - { - RINOK(copyCoder->Code(limitedStreamSpec, outStream, NULL, &outSize64, NULL)); - } - else - { - if (lzxMode) - { - lzxDecoderSpec->SetKeepHistory(false); - RINOK(lzxDecoder->Code(limitedStreamSpec, outStream, NULL, &outSize64, NULL)); - } - else - { - RINOK(xpressDecoder.Code(limitedStreamSpec, outStream, outSize)); - } - } - outProcessed += outSize; - } - return S_OK; -} - -HRESULT CUnpacker::Unpack(IInStream *inStream, const CResource &resource, bool lzxMode, - ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest) -{ - COutStreamWithSha1 *shaStreamSpec = new COutStreamWithSha1(); - CMyComPtr<ISequentialOutStream> shaStream = shaStreamSpec; - shaStreamSpec->SetStream(outStream); - shaStreamSpec->Init(digest != NULL); - HRESULT result = Unpack(inStream, resource, lzxMode, shaStream, progress); - if (digest) - shaStreamSpec->Final(digest); - return result; -} - -static HRESULT UnpackData(IInStream *inStream, const CResource &resource, bool lzxMode, CByteBuffer &buf, Byte *digest) -{ - size_t size = (size_t)resource.UnpackSize; - if (size != resource.UnpackSize) - return E_OUTOFMEMORY; - buf.Free(); - buf.SetCapacity(size); - - CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream(); - CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; - outStreamSpec->Init((Byte *)buf, size); - - CUnpacker unpacker; - return unpacker.Unpack(inStream, resource, lzxMode, outStream, NULL, digest); -} - -void CResource::Parse(const Byte *p) -{ - Flags = p[7]; - PackSize = Get64(p) & (((UInt64)1 << 56) - 1); - Offset = Get64(p + 8); - UnpackSize = Get64(p + 16); -} - -#define GetResource(p, res) res.Parse(p) - -static void GetStream(bool oldVersion, const Byte *p, CStreamInfo &s) -{ - s.Resource.Parse(p); - if (oldVersion) - { - s.PartNumber = 1; - s.Id = Get32(p + 24); - s.RefCount = Get32(p + 28); - memcpy(s.Hash, p + 32, kHashSize); - } - else - { - s.PartNumber = Get16(p + 24); - s.RefCount = Get32(p + 26); - memcpy(s.Hash, p + 30, kHashSize); - } -} - -static const wchar_t *kLongPath = L"[LongPath]"; - -UString CDatabase::GetItemPath(const int index1) const -{ - int size = 0; - int index = index1; - int newLevel; - for (newLevel = 0;; newLevel = 1) - { - const CItem &item = Items[index]; - index = item.Parent; - if (index >= 0 || !SkipRoot) - size += item.Name.Length() + newLevel; - if (index < 0) - break; - if ((UInt32)size >= ((UInt32)1 << 16)) - return kLongPath; - } - - wchar_t temp[16]; - int imageLen = 0; - if (ShowImageNumber) - { - ConvertUInt32ToString(-1 - index, temp); - imageLen = MyStringLen(temp); - size += imageLen + 1; - } - if ((UInt32)size >= ((UInt32)1 << 16)) - return kLongPath; - - UString path; - wchar_t *s = path.GetBuffer(size); - s[size] = 0; - if (ShowImageNumber) - { - memcpy(s, temp, imageLen * sizeof(wchar_t)); - s[imageLen] = WCHAR_PATH_SEPARATOR; - } - - index = index1; - - for (newLevel = 0;; newLevel = 1) - { - const CItem &item = Items[index]; - index = item.Parent; - if (index >= 0 || !SkipRoot) - { - if (newLevel) - s[--size] = WCHAR_PATH_SEPARATOR; - size -= item.Name.Length(); - memcpy(s + size, item.Name, sizeof(wchar_t) * item.Name.Length()); - } - if (index < 0) - { - path.ReleaseBuffer(); - return path; - } - } -} - -static void GetFileTimeFromMem(const Byte *p, FILETIME *ft) -{ - ft->dwLowDateTime = Get32(p); - ft->dwHighDateTime = Get32(p + 4); -} - -static HRESULT ReadName(const Byte *p, int size, UString &dest) -{ - if (size == 0) - return S_OK; - if (Get16(p + size) != 0) - return S_FALSE; - wchar_t *s = dest.GetBuffer(size / 2); - for (int i = 0; i <= size; i += 2) - *s++ = Get16(p + i); - dest.ReleaseBuffer(); - return S_OK; -} - -HRESULT CDatabase::ParseDirItem(size_t pos, int parent) -{ - if ((pos & 7) != 0) - return S_FALSE; - - int prevIndex = -1; - for (int numItems = 0;; numItems++) - { - if (OpenCallback) - { - UInt64 numFiles = Items.Size(); - if ((numFiles & 0x3FF) == 0) - { - RINOK(OpenCallback->SetCompleted(&numFiles, NULL)); - } - } - size_t rem = DirSize - pos; - if (pos < DirStartOffset || pos > DirSize || rem < 8) - return S_FALSE; - const Byte *p = DirData + pos; - UInt64 len = Get64(p); - if (len == 0) - { - if (parent < 0 && numItems != 1) - SkipRoot = false; - DirProcessed += 8; - return S_OK; - } - if ((len & 7) != 0 || rem < len) - return S_FALSE; - if (!IsOldVersion) - if (len < 0x28) - return S_FALSE; - DirProcessed += (size_t)len; - if (DirProcessed > DirSize) - return S_FALSE; - int extraOffset = 0; - if (IsOldVersion) - { - if (len < 0x40 || (/* Get32(p + 12) == 0 && */ Get32(p + 0x14) != 0)) - { - extraOffset = 0x10; - } - } - else if (Get64(p + 8) == 0) - extraOffset = 0x24; - if (extraOffset) - { - if (prevIndex == -1) - return S_FALSE; - UInt32 fileNameLen = Get16(p + extraOffset); - if ((fileNameLen & 1) != 0) - return S_FALSE; - /* Probably different versions of ImageX can use different number of - additional ZEROs. So we don't use exact check. */ - UInt32 fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2); - if (((extraOffset + 2 + fileNameLen2 + 6) & ~7) > len) - return S_FALSE; - - UString name; - RINOK(ReadName(p + extraOffset + 2, fileNameLen, name)); - - CItem &prevItem = Items[prevIndex]; - if (name.IsEmpty() && !prevItem.HasStream()) - { - if (IsOldVersion) - prevItem.Id = Get32(p + 8); - else - memcpy(prevItem.Hash, p + 0x10, kHashSize); - } - else - { - CItem item; - item.Name = prevItem.Name + L':' + name; - item.CTime = prevItem.CTime; - item.ATime = prevItem.ATime; - item.MTime = prevItem.MTime; - if (IsOldVersion) - { - item.Id = Get32(p + 8); - memset(item.Hash, 0, kHashSize); - } - else - memcpy(item.Hash, p + 0x10, kHashSize); - item.Attrib = 0; - item.Order = Order++; - item.Parent = parent; - Items.Add(item); - } - pos += (size_t)len; - continue; - } - - UInt32 dirRecordSize = IsOldVersion ? kDirRecordSizeOld : kDirRecordSize; - if (len < dirRecordSize) - return S_FALSE; - - CItem item; - item.Attrib = Get32(p + 8); - // item.SecurityId = Get32(p + 0xC); - UInt64 subdirOffset = Get64(p + 0x10); - UInt32 timeOffset = IsOldVersion ? 0x18: 0x28; - GetFileTimeFromMem(p + timeOffset, &item.CTime); - GetFileTimeFromMem(p + timeOffset + 8, &item.ATime); - GetFileTimeFromMem(p + timeOffset + 16, &item.MTime); - if (IsOldVersion) - { - item.Id = Get32(p + 0x10); - memset(item.Hash, 0, kHashSize); - } - else - { - memcpy(item.Hash, p + 0x40, kHashSize); - } - // UInt32 numStreams = Get16(p + dirRecordSize - 6); - UInt32 shortNameLen = Get16(p + dirRecordSize - 4); - UInt32 fileNameLen = Get16(p + dirRecordSize - 2); - - if ((shortNameLen & 1) != 0 || (fileNameLen & 1) != 0) - return S_FALSE; - - UInt32 shortNameLen2 = (shortNameLen == 0 ? shortNameLen : shortNameLen + 2); - UInt32 fileNameLen2 = (fileNameLen == 0 ? fileNameLen : fileNameLen + 2); - - if (((dirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7) > len) - return S_FALSE; - p += dirRecordSize; - - RINOK(ReadName(p, fileNameLen, item.Name)); - RINOK(ReadName(p + fileNameLen2, shortNameLen, item.ShortName)); - - if (parent < 0 && (shortNameLen || fileNameLen || !item.IsDir())) - SkipRoot = false; - - /* - // there are some extra data for some files. - p -= dirRecordSize; - p += ((dirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); - if (((dirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7) != len) - p = p; - */ - - /* - if (parent >= 0) - { - UString s = GetItemPath(parent) + L"\\" + item.Name; - printf("\n%s %8x %S", item.IsDir() ? "D" : " ", (int)subdirOffset, (const wchar_t *)s); - } - */ - - if (fileNameLen == 0 && item.IsDir() && !item.HasStream()) - item.Attrib = 0x10; // some swm archives have system/hidden attributes for root - - item.Parent = parent; - prevIndex = Items.Add(item); - if (item.IsDir() && subdirOffset != 0) - { - RINOK(ParseDirItem((size_t)subdirOffset, prevIndex)); - } - Items[prevIndex].Order = Order++; - pos += (size_t)len; - } -} - -HRESULT CDatabase::ParseImageDirs(const CByteBuffer &buf, int parent) -{ - DirData = buf; - DirSize = buf.GetCapacity(); - - size_t pos = 0; - if (DirSize < 8) - return S_FALSE; - const Byte *p = DirData; - UInt32 totalLength = Get32(p); - if (IsOldVersion) - { - for (pos = 4;; pos += 8) - { - if (pos + 4 > DirSize) - return S_FALSE; - UInt32 n = Get32(p + pos); - if (n == 0) - break; - if (pos + 8 > DirSize) - return S_FALSE; - totalLength += Get32(p + pos + 4); - if (totalLength > DirSize) - return S_FALSE; - } - pos += totalLength + 4; - pos = (pos + 7) & ~(size_t)7; - if (pos > DirSize) - return S_FALSE; - } - else - { - - // UInt32 numEntries = Get32(p + 4); - pos += 8; - { - /* - CRecordVector<UInt64> entryLens; - UInt64 sum = 0; - for (UInt32 i = 0; i < numEntries; i++) - { - if (pos + 8 > DirSize) - return S_FALSE; - UInt64 len = Get64(p + pos); - entryLens.Add(len); - sum += len; - pos += 8; - } - pos += (size_t)sum; // skip security descriptors - while ((pos & 7) != 0) - pos++; - if (pos != totalLength) - return S_FALSE; - */ - if (totalLength == 0) - pos = 8; - else if (totalLength < 8) - return S_FALSE; - else - pos = totalLength; - } - } - DirStartOffset = DirProcessed = pos; - RINOK(ParseDirItem(pos, parent)); - if (DirProcessed == DirSize) - return S_OK; - /* Original program writes additional 8 bytes (END_OF_ROOT_FOLDER), but - reference to that folder is empty */ - if (DirProcessed == DirSize - 8 && DirProcessed - DirStartOffset == 112 && - Get64(p + DirSize - 8) == 0) - return S_OK; - return S_FALSE; -} - -HRESULT CHeader::Parse(const Byte *p) -{ - UInt32 headerSize = Get32(p + 8); - Version = Get32(p + 0x0C); - Flags = Get32(p + 0x10); - if (!IsSupported()) - return S_FALSE; - ChunkSize = Get32(p + 0x14); - if (ChunkSize != kChunkSize && ChunkSize != 0) - return S_FALSE; - int offset; - if (IsOldVersion()) - { - if (headerSize != 0x60) - return S_FALSE; - memset(Guid, 0, 16); - offset = 0x18; - PartNumber = 1; - NumParts = 1; - } - else - { - if (headerSize < 0x74) - return S_FALSE; - memcpy(Guid, p + 0x18, 16); - PartNumber = Get16(p + 0x28); - NumParts = Get16(p + 0x2A); - offset = 0x2C; - if (IsNewVersion()) - { - NumImages = Get32(p + offset); - offset += 4; - } - } - GetResource(p + offset, OffsetResource); - GetResource(p + offset + 0x18, XmlResource); - GetResource(p + offset + 0x30, MetadataResource); - if (IsNewVersion()) - { - if (headerSize < 0xD0) - return S_FALSE; - BootIndex = Get32(p + 0x48); - IntegrityResource.Parse(p + offset + 0x4C); - } - return S_OK; -} - -const Byte kSignature[kSignatureSize] = { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }; - -HRESULT ReadHeader(IInStream *inStream, CHeader &h) -{ - Byte p[kHeaderSizeMax]; - RINOK(ReadStream_FALSE(inStream, p, kHeaderSizeMax)); - if (memcmp(p, kSignature, kSignatureSize) != 0) - return S_FALSE; - return h.Parse(p); -} - -static HRESULT ReadStreams(bool oldVersion, IInStream *inStream, const CHeader &h, CDatabase &db) -{ - CByteBuffer offsetBuf; - RINOK(UnpackData(inStream, h.OffsetResource, h.IsLzxMode(), offsetBuf, NULL)); - size_t i; - size_t streamInfoSize = oldVersion ? kStreamInfoSize + 2 : kStreamInfoSize; - for (i = 0; offsetBuf.GetCapacity() - i >= streamInfoSize; i += streamInfoSize) - { - CStreamInfo s; - GetStream(oldVersion, (const Byte *)offsetBuf + i, s); - if (s.PartNumber == h.PartNumber) - db.Streams.Add(s); - } - return (i == offsetBuf.GetCapacity()) ? S_OK : S_FALSE; -} - -static bool IsEmptySha(const Byte *data) -{ - for (int i = 0; i < kHashSize; i++) - if (data[i] != 0) - return false; - return true; -} - -HRESULT CDatabase::Open(IInStream *inStream, const CHeader &h, CByteBuffer &xml, IArchiveOpenCallback *openCallback) -{ - OpenCallback = openCallback; - IsOldVersion = h.IsOldVersion(); - RINOK(UnpackData(inStream, h.XmlResource, h.IsLzxMode(), xml, NULL)); - RINOK(ReadStreams(h.IsOldVersion(), inStream, h, *this)); - bool needBootMetadata = !h.MetadataResource.IsEmpty(); - Order = 0; - if (h.PartNumber == 1) - { - int imageIndex = 1; - for (int i = 0; i < Streams.Size(); i++) - { - // if (imageIndex > 1) break; - const CStreamInfo &si = Streams[i]; - if (!si.Resource.IsMetadata() || si.PartNumber != h.PartNumber) - continue; - Byte hash[kHashSize]; - CByteBuffer metadata; - RINOK(UnpackData(inStream, si.Resource, h.IsLzxMode(), metadata, hash)); - if (memcmp(hash, si.Hash, kHashSize) != 0 && - !(h.IsOldVersion() && IsEmptySha(si.Hash))) - return S_FALSE; - NumImages++; - RINOK(ParseImageDirs(metadata, -(int)(++imageIndex))); - if (needBootMetadata) - if (h.MetadataResource.Offset == si.Resource.Offset) - needBootMetadata = false; - } - } - - if (needBootMetadata) - { - CByteBuffer metadata; - RINOK(UnpackData(inStream, h.MetadataResource, h.IsLzxMode(), metadata, NULL)); - RINOK(ParseImageDirs(metadata, -1)); - NumImages++; - } - return S_OK; -} - - -static int CompareStreamsByPos(const CStreamInfo *p1, const CStreamInfo *p2, void * /* param */) -{ - int res = MyCompare(p1->PartNumber, p2->PartNumber); - if (res != 0) - return res; - return MyCompare(p1->Resource.Offset, p2->Resource.Offset); -} - -static int CompareIDs(const int *p1, const int *p2, void *param) -{ - const CRecordVector<CStreamInfo> &streams = *(const CRecordVector<CStreamInfo> *)param; - return MyCompare(streams[*p1].Id, streams[*p2].Id); -} - -static int CompareHashRefs(const int *p1, const int *p2, void *param) -{ - const CRecordVector<CStreamInfo> &streams = *(const CRecordVector<CStreamInfo> *)param; - return memcmp(streams[*p1].Hash, streams[*p2].Hash, kHashSize); -} - -static int FindId(const CRecordVector<CStreamInfo> &streams, - const CIntVector &sortedByHash, UInt32 id) -{ - int left = 0, right = streams.Size(); - while (left != right) - { - int mid = (left + right) / 2; - int streamIndex = sortedByHash[mid]; - UInt32 id2 = streams[streamIndex].Id; - if (id == id2) - return streamIndex; - if (id < id2) - right = mid; - else - left = mid + 1; - } - return -1; -} - -static int FindHash(const CRecordVector<CStreamInfo> &streams, - const CIntVector &sortedByHash, const Byte *hash) -{ - int left = 0, right = streams.Size(); - while (left != right) - { - int mid = (left + right) / 2; - int streamIndex = sortedByHash[mid]; - UInt32 i; - const Byte *hash2 = streams[streamIndex].Hash; - for (i = 0; i < kHashSize; i++) - if (hash[i] != hash2[i]) - break; - if (i == kHashSize) - return streamIndex; - if (hash[i] < hash2[i]) - right = mid; - else - left = mid + 1; - } - return -1; -} - -static int CompareItems(const int *a1, const int *a2, void *param) -{ - const CObjectVector<CItem> &items = ((CDatabase *)param)->Items; - const CItem &i1 = items[*a1]; - const CItem &i2 = items[*a2]; - - if (i1.IsDir() != i2.IsDir()) - return i1.IsDir() ? 1 : -1; - int res = MyCompare(i1.StreamIndex, i2.StreamIndex); - if (res != 0) - return res; - return MyCompare(i1.Order, i2.Order); -} - -HRESULT CDatabase::Sort(bool skipRootDir) -{ - Streams.Sort(CompareStreamsByPos, NULL); - - { - CIntVector sortedByHash; - { - for (int i = 0; i < Streams.Size(); i++) - sortedByHash.Add(i); - if (IsOldVersion) - sortedByHash.Sort(CompareIDs, &Streams); - else - sortedByHash.Sort(CompareHashRefs, &Streams); - } - - for (int i = 0; i < Items.Size(); i++) - { - CItem &item = Items[i]; - item.StreamIndex = -1; - if (item.HasStream()) - if (IsOldVersion) - item.StreamIndex = FindId(Streams, sortedByHash, item.Id); - else - item.StreamIndex = FindHash(Streams, sortedByHash, item.Hash); - } - } - - { - CRecordVector<bool> used; - int i; - for (i = 0; i < Streams.Size(); i++) - { - const CStreamInfo &s = Streams[i]; - used.Add(s.Resource.IsMetadata() && s.PartNumber == 1); - // used.Add(false); - } - for (i = 0; i < Items.Size(); i++) - { - CItem &item = Items[i]; - if (item.StreamIndex >= 0) - used[item.StreamIndex] = true; - } - for (i = 0; i < Streams.Size(); i++) - if (!used[i]) - { - CItem item; - item.StreamIndex = i; - item.HasMetadata = false; - Items.Add(item); - } - } - - SortedItems.Reserve(Items.Size()); - for (int i = (skipRootDir ? 1 : 0); i < Items.Size(); i++) - SortedItems.Add(i); - SortedItems.Sort(CompareItems, this); - return S_OK; -} - -}} diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.h b/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.h deleted file mode 100644 index da3e28a56..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.h +++ /dev/null @@ -1,297 +0,0 @@ -// Archive/WimIn.h - -#ifndef __ARCHIVE_WIM_IN_H -#define __ARCHIVE_WIM_IN_H - -#include "Common/Buffer.h" -#include "Common/MyString.h" - -#include "../../Compress/CopyCoder.h" -#include "../../Compress/LzxDecoder.h" - -#include "../IArchive.h" - -namespace NArchive { -namespace NWim { - -namespace NXpress { - -class CBitStream -{ - CInBuffer m_Stream; - UInt32 m_Value; - unsigned m_BitPos; -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() { m_Stream.Init(); m_BitPos = 0; } - // UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - m_BitPos / 8; } - Byte DirectReadByte() { return m_Stream.ReadByte(); } - - void Normalize() - { - if (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; - m_BitPos += 16; - } - } - - UInt32 GetValue(unsigned numBits) - { - Normalize(); - return (m_Value >> (m_BitPos - numBits)) & ((1 << numBits) - 1); - } - - void MovePos(unsigned numBits) { m_BitPos -= numBits; } - - UInt32 ReadBits(unsigned numBits) - { - UInt32 res = GetValue(numBits); - m_BitPos -= numBits; - return res; - } -}; - -const unsigned kNumHuffmanBits = 16; -const UInt32 kMatchMinLen = 3; -const UInt32 kNumLenSlots = 16; -const UInt32 kNumPosSlots = 16; -const UInt32 kNumPosLenSlots = kNumPosSlots * kNumLenSlots; -const UInt32 kMainTableSize = 256 + kNumPosLenSlots; - -class CDecoder -{ - CBitStream m_InBitStream; - CLzOutWindow m_OutWindowStream; - NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; - - HRESULT CodeSpec(UInt32 size); - HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize); -public: - void ReleaseStreams() - { - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - } - HRESULT Flush() { return m_OutWindowStream.Flush(); } - HRESULT Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt32 outSize); -}; - -} - -namespace NResourceFlags -{ - const Byte kFree = 1; - const Byte kMetadata = 2; - const Byte Compressed = 4; - const Byte Spanned = 4; -} - -struct CResource -{ - UInt64 PackSize; - UInt64 Offset; - UInt64 UnpackSize; - Byte Flags; - - void Clear() - { - PackSize = 0; - Offset = 0; - UnpackSize = 0; - Flags = 0; - } - void Parse(const Byte *p); - void WriteTo(Byte *p) const; - bool IsFree() const { return (Flags & NResourceFlags::kFree) != 0; } - bool IsMetadata() const { return (Flags & NResourceFlags::kMetadata) != 0; } - bool IsCompressed() const { return (Flags & NResourceFlags::Compressed) != 0; } - bool IsEmpty() const { return (UnpackSize == 0); } -}; - -namespace NHeaderFlags -{ - const UInt32 kCompression = 2; - const UInt32 kSpanned = 8; - const UInt32 kRpFix = 0x80; - const UInt32 kXPRESS = 0x20000; - const UInt32 kLZX = 0x40000; -} - -const UInt32 kWimVersion = 0x010D00; -const UInt32 kHeaderSizeMax = 0xD0; -const UInt32 kSignatureSize = 8; -extern const Byte kSignature[kSignatureSize]; -const unsigned kChunkSizeBits = 15; -const UInt32 kChunkSize = (1 << kChunkSizeBits); - -struct CHeader -{ - UInt32 Version; - UInt32 Flags; - UInt32 ChunkSize; - Byte Guid[16]; - UInt16 PartNumber; - UInt16 NumParts; - UInt32 NumImages; - - CResource OffsetResource; - CResource XmlResource; - CResource MetadataResource; - CResource IntegrityResource; - UInt32 BootIndex; - - void SetDefaultFields(bool useLZX); - - void WriteTo(Byte *p) const; - HRESULT Parse(const Byte *p); - bool IsCompressed() const { return (Flags & NHeaderFlags::kCompression) != 0; } - bool IsSupported() const { return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0 || (Flags & NHeaderFlags::kXPRESS) != 0 ) ; } - bool IsLzxMode() const { return (Flags & NHeaderFlags::kLZX) != 0; } - bool IsSpanned() const { return (!IsCompressed() || (Flags & NHeaderFlags::kSpanned) != 0); } - bool IsOldVersion() const { return (Version <= 0x010A00); } - bool IsNewVersion() const { return (Version > 0x010C00); } - - bool AreFromOnArchive(const CHeader &h) - { - return (memcmp(Guid, h.Guid, sizeof(Guid)) == 0) && (h.NumParts == NumParts); - } -}; - -const UInt32 kHashSize = 20; -const UInt32 kStreamInfoSize = 24 + 2 + 4 + kHashSize; - -struct CStreamInfo -{ - CResource Resource; - UInt16 PartNumber; - UInt32 RefCount; - UInt32 Id; - BYTE Hash[kHashSize]; - - void WriteTo(Byte *p) const; -}; - -const UInt32 kDirRecordSizeOld = 62; -const UInt32 kDirRecordSize = 102; - -struct CItem -{ - UString Name; - UString ShortName; - UInt32 Attrib; - // UInt32 SecurityId; - BYTE Hash[kHashSize]; - UInt32 Id; - FILETIME CTime; - FILETIME ATime; - FILETIME MTime; - // UInt32 ReparseTag; - // UInt64 HardLink; - // UInt16 NumStreams; - int StreamIndex; - int Parent; - unsigned Order; - bool HasMetadata; - CItem(): HasMetadata(true), StreamIndex(-1), Id(0) {} - bool IsDir() const { return HasMetadata && ((Attrib & 0x10) != 0); } - bool HasStream() const - { - for (unsigned i = 0; i < kHashSize; i++) - if (Hash[i] != 0) - return true; - return Id != 0; - } -}; - -class CDatabase -{ - const Byte *DirData; - size_t DirSize; - size_t DirProcessed; - size_t DirStartOffset; - int Order; - IArchiveOpenCallback *OpenCallback; - - HRESULT ParseDirItem(size_t pos, int parent); - HRESULT ParseImageDirs(const CByteBuffer &buf, int parent); - -public: - CRecordVector<CStreamInfo> Streams; - CObjectVector<CItem> Items; - CIntVector SortedItems; - int NumImages; - bool SkipRoot; - bool ShowImageNumber; - - bool IsOldVersion; - - UInt64 GetUnpackSize() const - { - UInt64 res = 0; - for (int i = 0; i < Streams.Size(); i++) - res += Streams[i].Resource.UnpackSize; - return res; - } - - UInt64 GetPackSize() const - { - UInt64 res = 0; - for (int i = 0; i < Streams.Size(); i++) - res += Streams[i].Resource.PackSize; - return res; - } - - void Clear() - { - Streams.Clear(); - Items.Clear(); - SortedItems.Clear(); - NumImages = 0; - - SkipRoot = true; - ShowImageNumber = true; - IsOldVersion = false; - } - - UString GetItemPath(int index) const; - - HRESULT Open(IInStream *inStream, const CHeader &h, CByteBuffer &xml, IArchiveOpenCallback *openCallback); - - void DetectPathMode() - { - ShowImageNumber = (NumImages != 1); - } - - HRESULT Sort(bool skipRootDir); -}; - -HRESULT ReadHeader(IInStream *inStream, CHeader &header); - -class CUnpacker -{ - NCompress::CCopyCoder *copyCoderSpec; - CMyComPtr<ICompressCoder> copyCoder; - - NCompress::NLzx::CDecoder *lzxDecoderSpec; - CMyComPtr<ICompressCoder> lzxDecoder; - - NXpress::CDecoder xpressDecoder; - - CByteBuffer sizesBuf; - HRESULT Unpack(IInStream *inStream, const CResource &res, bool lzxMode, - ISequentialOutStream *outStream, ICompressProgressInfo *progress); -public: - HRESULT Unpack(IInStream *inStream, const CResource &res, bool lzxMode, - ISequentialOutStream *outStream, ICompressProgressInfo *progress, Byte *digest); -}; - -}} - -#endif diff --git a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimRegister.cpp b/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimRegister.cpp deleted file mode 100644 index 8da914360..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/Wim/WimRegister.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// WimRegister.cpp - -#include "StdAfx.h" - -#include "../../Common/RegisterArc.h" - -#include "WimHandler.h" -static IInArchive *CreateArc() { return new NArchive::NWim::CHandler; } -#ifndef EXTRACT_ONLY -static IOutArchive *CreateArcOut() { return new NArchive::NWim::COutHandler; } -#else -#define CreateArcOut 0 -#endif - -static CArcInfo g_ArcInfo = - { L"wim", L"wim swm", 0, 0xE6, { 'M', 'S', 'W', 'I', 'M', 0, 0, 0 }, 8, false, CreateArc, CreateArcOut }; - -REGISTER_ARC(Wim) |