summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/7zip/Archive/Wim
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/Wim')
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/StdAfx.h8
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.cpp660
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandler.h77
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/WimHandlerOut.cpp639
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.cpp855
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/WimIn.h297
-rw-r--r--src/libs/7zip/win/CPP/7zip/Archive/Wim/WimRegister.cpp18
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)