mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 08:07:12 -06:00
Update to 7-Zip Version 21.07
See: https://sourceforge.net/p/sevenzip/discussion/45797/thread/0a7b47970b/
This commit is contained in:
@@ -130,8 +130,10 @@ HRESULT CHandler::SetMainMethod(CCompressionMethodMode &methodMode)
|
||||
CMethodFull &methodFull = methodMode.Methods.AddNew();
|
||||
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
methodFull.Set_NumThreads = true;
|
||||
methodFull.NumThreads = methodMode.NumThreads;
|
||||
#endif
|
||||
|
||||
if (methodFull.Id != k_Copy)
|
||||
needSolid = true;
|
||||
|
||||
@@ -320,7 +320,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
break;
|
||||
}
|
||||
|
||||
case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break;
|
||||
case kpidBlock: prop.Set_Int32((Int32)m_Database.GetFolderIndex(&mvItem)); break;
|
||||
|
||||
#ifdef _CAB_DETAILS
|
||||
|
||||
|
||||
@@ -120,6 +120,15 @@ static void SetMethodProp32(CMethodProps &m, PROPID propID, UInt32 value)
|
||||
m.AddProp32(propID, value);
|
||||
}
|
||||
|
||||
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
|
||||
{
|
||||
UInt32 level = _level;
|
||||
if (level != (UInt32)(Int32)-1)
|
||||
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
|
||||
}
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value)
|
||||
{
|
||||
const int i = m.FindProp(propID);
|
||||
@@ -132,14 +141,6 @@ static void SetMethodProp32_Replace(CMethodProps &m, PROPID propID, UInt32 value
|
||||
m.AddProp32(propID, value);
|
||||
}
|
||||
|
||||
void CMultiMethodProps::SetGlobalLevelTo(COneMethodInfo &oneMethodInfo) const
|
||||
{
|
||||
UInt32 level = _level;
|
||||
if (level != (UInt32)(Int32)-1)
|
||||
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
|
||||
}
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
void CMultiMethodProps::SetMethodThreadsTo_IfNotFinded(CMethodProps &oneMethodInfo, UInt32 numThreads)
|
||||
{
|
||||
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
@@ -149,7 +150,9 @@ void CMultiMethodProps::SetMethodThreadsTo_Replace(CMethodProps &oneMethodInfo,
|
||||
{
|
||||
SetMethodProp32_Replace(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _7ZIP_ST
|
||||
|
||||
|
||||
void CMultiMethodProps::InitMulti()
|
||||
{
|
||||
|
||||
@@ -234,6 +234,7 @@ static const CAppleName k_Names[] =
|
||||
{ true, "hfs", "Apple_HFS" },
|
||||
{ true, "hfsx", "Apple_HFSX" },
|
||||
{ true, "ufs", "Apple_UFS" },
|
||||
{ true, "apfs", "Apple_APFS" },
|
||||
|
||||
// efi_sys partition is FAT32, but it's not main file. So we use (IsFs = false)
|
||||
{ false, "efi_sys", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" },
|
||||
|
||||
@@ -935,7 +935,10 @@ HRESULT CHandler::ParseDir(const Byte *p, size_t size, unsigned iNodeDir)
|
||||
return S_FALSE;
|
||||
|
||||
if (_isUTF)
|
||||
_isUTF = CheckUTF8_AString(item.Name);
|
||||
{
|
||||
// 21.07 : we force UTF8
|
||||
// _isUTF = CheckUTF8_AString(item.Name);
|
||||
}
|
||||
|
||||
if (iNode == 0)
|
||||
{
|
||||
@@ -1835,7 +1838,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
|
||||
case kpidRevision: prop = _h.RevLevel; break;
|
||||
|
||||
case kpidINodeSize: prop = _h.InodeSize; break;
|
||||
case kpidINodeSize: prop = (UInt32)_h.InodeSize; break;
|
||||
|
||||
case kpidId:
|
||||
{
|
||||
|
||||
@@ -112,6 +112,7 @@ static const CPartType kPartTypes[] =
|
||||
{ 0x516E7CB8, "zfs", "FreeBSD ZFS" },
|
||||
|
||||
{ 0x48465300, "hfsx", "HFS+" },
|
||||
{ 0x7C3457EF, "apfs", "APFS" },
|
||||
};
|
||||
|
||||
static int FindPartType(const Byte *guid)
|
||||
|
||||
@@ -105,10 +105,9 @@ STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
|
||||
|
||||
|
||||
CHandlerImg::CHandlerImg():
|
||||
_imgExt(NULL)
|
||||
CHandlerImg::CHandlerImg()
|
||||
{
|
||||
ClearStreamVars();
|
||||
Clear_HandlerImg_Vars();
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
@@ -121,7 +120,11 @@ STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosit
|
||||
default: return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
if (offset < 0)
|
||||
{
|
||||
if (newPosition)
|
||||
*newPosition = _virtPos;
|
||||
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
|
||||
}
|
||||
_virtPos = offset;
|
||||
if (newPosition)
|
||||
*newPosition = offset;
|
||||
@@ -130,6 +133,7 @@ STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosit
|
||||
|
||||
static const Byte k_GDP_Signature[] = { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' };
|
||||
|
||||
|
||||
static const char *GetImgExt(ISequentialInStream *stream)
|
||||
{
|
||||
const size_t kHeaderSize = 1 << 10;
|
||||
@@ -151,6 +155,15 @@ void CHandlerImg::CloseAtError()
|
||||
Stream.Release();
|
||||
}
|
||||
|
||||
void CHandlerImg::Clear_HandlerImg_Vars()
|
||||
{
|
||||
_imgExt = NULL;
|
||||
_size = 0;
|
||||
ClearStreamVars();
|
||||
Reset_VirtPos();
|
||||
Reset_PosInArc();
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandlerImg::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * openCallback)
|
||||
@@ -165,9 +178,16 @@ STDMETHODIMP CHandlerImg::Open(IInStream *stream,
|
||||
if (res == S_OK)
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> inStream;
|
||||
HRESULT res2 = GetStream(0, &inStream);
|
||||
const HRESULT res2 = GetStream(0, &inStream);
|
||||
if (res2 == S_OK && inStream)
|
||||
_imgExt = GetImgExt(inStream);
|
||||
// _imgExt = GetImgExt(this); // for debug
|
||||
/* we reset (_virtPos) to support cases, if some code will
|
||||
call Read() from Handler object instead of GetStream() object. */
|
||||
Reset_VirtPos();
|
||||
// optional: we reset (_posInArc). if real seek position of stream will be changed in external code
|
||||
Reset_PosInArc();
|
||||
// optional: here we could also reset seek positions in parent streams..
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,9 @@ protected:
|
||||
// bool _stream_UsePackSize;
|
||||
// UInt64 _stream_PackSize;
|
||||
|
||||
void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; }
|
||||
void Reset_VirtPos() { _virtPos = (UInt64)0; }
|
||||
|
||||
void ClearStreamVars()
|
||||
{
|
||||
_stream_unavailData = false;
|
||||
@@ -87,6 +90,7 @@ protected:
|
||||
// _stream_PackSize = 0;
|
||||
}
|
||||
|
||||
void Clear_HandlerImg_Vars(); // it doesn't Release (Stream) var.
|
||||
|
||||
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
|
||||
virtual void CloseAtError();
|
||||
|
||||
@@ -451,7 +451,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
|
||||
REGISTER_ARC_I(
|
||||
"lzip", "lz tlz", "* .tar", 0xC4,
|
||||
"lzip", "lz tlz", "* .tar", 0xC3,
|
||||
k_Signature,
|
||||
0,
|
||||
NArcInfoFlags::kKeepName,
|
||||
|
||||
@@ -601,7 +601,6 @@ STDMETHODIMP CHandler::Close()
|
||||
_table.Free();
|
||||
_dir.Free();
|
||||
_phySize = 0;
|
||||
_size = 0;
|
||||
|
||||
_cacheCluster = (UInt64)(Int64)-1;
|
||||
_comprPos = 0;
|
||||
@@ -611,7 +610,8 @@ STDMETHODIMP CHandler::Close()
|
||||
_isArc = false;
|
||||
_unsupported = false;
|
||||
|
||||
_imgExt = NULL;
|
||||
// CHandlerImg:
|
||||
Clear_HandlerImg_Vars();
|
||||
Stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ public:
|
||||
{
|
||||
_needChangeForNext = true;
|
||||
_after.Empty();
|
||||
UString base = name;
|
||||
int dotPos = name.ReverseFind_Dot();
|
||||
UString base (name);
|
||||
const int dotPos = name.ReverseFind_Dot();
|
||||
|
||||
if (dotPos >= 0)
|
||||
{
|
||||
const UString ext = name.Ptr(dotPos + 1);
|
||||
const UString ext (name.Ptr(dotPos + 1));
|
||||
if (ext.IsEqualTo_Ascii_NoCase("rar"))
|
||||
{
|
||||
_after = name.Ptr(dotPos);
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
|
||||
#include "../Compress/CopyCoder.h"
|
||||
#include "../Compress/LzmaDecoder.h"
|
||||
#include "../Compress/LzmaEncoder.h"
|
||||
#include "../Compress/ZlibDecoder.h"
|
||||
#include "../Compress/ZlibEncoder.h"
|
||||
|
||||
#include "Common/DummyOutStream.h"
|
||||
|
||||
// #define SWF_UPDATE
|
||||
|
||||
#ifdef SWF_UPDATE
|
||||
|
||||
#include "../Compress/LzmaEncoder.h"
|
||||
#include "../Compress/ZlibEncoder.h"
|
||||
|
||||
#include "Common/HandlerOut.h"
|
||||
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
@@ -152,8 +160,10 @@ struct CItem
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IArchiveOpenSeq,
|
||||
#ifdef SWF_UPDATE
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
#endif
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CItem _item;
|
||||
@@ -162,16 +172,22 @@ class CHandler:
|
||||
CMyComPtr<ISequentialInStream> _seqStream;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
|
||||
#ifdef SWF_UPDATE
|
||||
CSingleMethodProps _props;
|
||||
bool _lzmaMode;
|
||||
#endif
|
||||
|
||||
public:
|
||||
CHandler(): _lzmaMode(false) {}
|
||||
#ifdef SWF_UPDATE
|
||||
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
||||
INTERFACE_IInArchive(;)
|
||||
CHandler(): _lzmaMode(false) {}
|
||||
INTERFACE_IOutArchive(;)
|
||||
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
|
||||
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
|
||||
#else
|
||||
MY_UNKNOWN_IMP2(IInArchive, IArchiveOpenSeq)
|
||||
#endif
|
||||
INTERFACE_IInArchive(;)
|
||||
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
|
||||
};
|
||||
|
||||
static const Byte kProps[] =
|
||||
@@ -416,6 +432,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
#ifdef SWF_UPDATE
|
||||
|
||||
static HRESULT UpdateArchive(ISequentialOutStream *outStream, UInt64 size,
|
||||
bool lzmaMode, const CSingleMethodProps &props,
|
||||
IArchiveUpdateCallback *updateCallback)
|
||||
@@ -576,11 +595,14 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static const Byte k_Signature[] = {
|
||||
3, 'C', 'W', 'S',
|
||||
3, 'Z', 'W', 'S' };
|
||||
|
||||
REGISTER_ARC_IO(
|
||||
REGISTER_ARC_I(
|
||||
"SWFc", "swf", "~.swf", 0xD8,
|
||||
k_Signature,
|
||||
0,
|
||||
|
||||
@@ -107,8 +107,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
|
||||
case kpidCharacts:
|
||||
{
|
||||
AString s = _encodingCharacts.GetCharactsString();
|
||||
prop = s;
|
||||
prop = _encodingCharacts.GetCharactsString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
return E_INVALIDARG;
|
||||
else
|
||||
ui.Mode = prop.ulVal;
|
||||
// FIXME : we can clear high file type bits to be more compatible with tars created by GNU TAR.
|
||||
// ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
|
||||
// 21.07 : we clear high file type bits as GNU TAR.
|
||||
ui.Mode &= ~(UInt32)MY_LIN_S_IFMT;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -17,7 +17,10 @@ namespace NFileHeader {
|
||||
// const char * const kUsTar = "ustar"; // 5 chars
|
||||
// const char * const kGNUTar = "GNUtar "; // 7 chars and a null
|
||||
// const char * const kEmpty = "\0\0\0\0\0\0\0\0";
|
||||
const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
|
||||
// 7-Zip used kUsTar_00 before 21.07:
|
||||
// const char kUsTar_00[8] = { 'u', 's', 't', 'a', 'r', 0, '0', '0' } ;
|
||||
// GNU TAR uses such header:
|
||||
const char kUsTar_GNU[8] = { 'u', 's', 't', 'a', 'r', ' ', ' ', 0 } ;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
@@ -76,7 +76,8 @@ namespace NFileHeader
|
||||
// extern const char * const kUsTar; // = "ustar"; // 5 chars
|
||||
// extern const char * const kGNUTar; // = "GNUtar "; // 7 chars and a null
|
||||
// extern const char * const kEmpty; // = "\0\0\0\0\0\0\0\0"
|
||||
extern const char kUsTar_00[8];
|
||||
// extern const char kUsTar_00[8];
|
||||
extern const char kUsTar_GNU[8];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,7 @@ static bool IsRecordLast(const char *buf)
|
||||
|
||||
static void ReadString(const char *s, unsigned size, AString &result)
|
||||
{
|
||||
char temp[NFileHeader::kRecordSize + 1];
|
||||
MyStrNCpy(temp, s, size);
|
||||
temp[size] = '\0';
|
||||
result = temp;
|
||||
result.SetFrom_CalcLen(s, size);
|
||||
}
|
||||
|
||||
static bool ParseInt64(const char *p, Int64 &val)
|
||||
|
||||
@@ -43,6 +43,15 @@ struct CItem
|
||||
|
||||
CRecordVector<CSparseBlock> SparseBlocks;
|
||||
|
||||
void SetDefaultWriteFields()
|
||||
{
|
||||
DeviceMajorDefined = false;
|
||||
DeviceMinorDefined = false;
|
||||
UID = 0;
|
||||
GID = 0;
|
||||
memcpy(Magic, NFileHeader::NMagic::kUsTar_GNU, 8);
|
||||
}
|
||||
|
||||
bool IsSymLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymLink && (Size == 0); }
|
||||
bool IsHardLink() const { return LinkFlag == NFileHeader::NLinkFlag::kHardLink; }
|
||||
bool IsSparse() const { return LinkFlag == NFileHeader::NLinkFlag::kSparse; }
|
||||
@@ -103,7 +112,7 @@ struct CItem
|
||||
bool IsUstarMagic() const
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
if (Magic[i] != NFileHeader::NMagic::kUsTar_00[i])
|
||||
if (Magic[i] != NFileHeader::NMagic::kUsTar_GNU[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,17 +15,6 @@ HRESULT COutArchive::WriteBytes(const void *data, unsigned size)
|
||||
return WriteStream(m_Stream, data, size);
|
||||
}
|
||||
|
||||
static void MyStrNCpy(char *dest, const char *src, unsigned size)
|
||||
{
|
||||
for (unsigned i = 0; i < size; i++)
|
||||
{
|
||||
char c = src[i];
|
||||
dest[i] = c;
|
||||
if (c == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool WriteOctal_8(char *s, UInt32 val)
|
||||
{
|
||||
const unsigned kNumDigits = 8 - 1;
|
||||
@@ -39,6 +28,12 @@ static bool WriteOctal_8(char *s, UInt32 val)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WriteBin_64bit(char *s, UInt64 val)
|
||||
{
|
||||
for (unsigned i = 0; i < 8; i++, val <<= 8)
|
||||
s[i] = (char)(val >> 56);
|
||||
}
|
||||
|
||||
static void WriteOctal_12(char *s, UInt64 val)
|
||||
{
|
||||
const unsigned kNumDigits = 12 - 1;
|
||||
@@ -47,8 +42,7 @@ static void WriteOctal_12(char *s, UInt64 val)
|
||||
// GNU extension;
|
||||
s[0] = (char)(Byte)0x80;
|
||||
s[1] = s[2] = s[3] = 0;
|
||||
for (unsigned i = 0; i < 8; i++, val <<= 8)
|
||||
s[4 + i] = (char)(val >> 56);
|
||||
WriteBin_64bit(s + 4, val);
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < kNumDigits; i++)
|
||||
@@ -66,61 +60,67 @@ static void WriteOctal_12_Signed(char *s, Int64 val)
|
||||
return;
|
||||
}
|
||||
s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF;
|
||||
for (unsigned i = 0; i < 8; i++, val <<= 8)
|
||||
s[4 + i] = (char)(val >> 56);
|
||||
WriteBin_64bit(s + 4, val);
|
||||
}
|
||||
|
||||
static bool CopyString(char *dest, const AString &src, unsigned maxSize)
|
||||
static void CopyString(char *dest, const AString &src, unsigned maxSize)
|
||||
{
|
||||
if (src.Len() >= maxSize)
|
||||
return false;
|
||||
MyStringCopy(dest, (const char *)src);
|
||||
return true;
|
||||
unsigned len = src.Len();
|
||||
if (len == 0)
|
||||
return;
|
||||
// 21.07: we don't require additional 0 character at the end
|
||||
if (len > maxSize)
|
||||
{
|
||||
len = maxSize;
|
||||
// return false;
|
||||
}
|
||||
memcpy(dest, src.Ptr(), len);
|
||||
// return true;
|
||||
}
|
||||
|
||||
#define RETURN_IF_NOT_TRUE(x) { if (!(x)) return E_FAIL; }
|
||||
|
||||
#define COPY_STRING_CHECK(dest, src, size) \
|
||||
CopyString(dest, src, size); dest += (size);
|
||||
|
||||
#define WRITE_OCTAL_8_CHECK(dest, src) \
|
||||
RETURN_IF_NOT_TRUE(WriteOctal_8(dest, src));
|
||||
|
||||
|
||||
HRESULT COutArchive::WriteHeaderReal(const CItem &item)
|
||||
{
|
||||
char record[NFileHeader::kRecordSize];
|
||||
memset(record, 0, NFileHeader::kRecordSize);
|
||||
char *cur = record;
|
||||
|
||||
if (item.Name.Len() > NFileHeader::kNameSize)
|
||||
return E_FAIL;
|
||||
MyStrNCpy(cur, item.Name, NFileHeader::kNameSize);
|
||||
cur += NFileHeader::kNameSize;
|
||||
COPY_STRING_CHECK (cur, item.Name, NFileHeader::kNameSize);
|
||||
|
||||
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.Mode)); cur += 8;
|
||||
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.UID)); cur += 8;
|
||||
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.GID)); cur += 8;
|
||||
WRITE_OCTAL_8_CHECK (cur, item.Mode); cur += 8;
|
||||
WRITE_OCTAL_8_CHECK (cur, item.UID); cur += 8;
|
||||
WRITE_OCTAL_8_CHECK (cur, item.GID); cur += 8;
|
||||
|
||||
WriteOctal_12(cur, item.PackSize); cur += 12;
|
||||
WriteOctal_12_Signed(cur, item.MTime); cur += 12;
|
||||
|
||||
memset(cur, ' ', 8);
|
||||
memset(cur, ' ', 8); // checksum field
|
||||
cur += 8;
|
||||
|
||||
*cur++ = item.LinkFlag;
|
||||
|
||||
RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize));
|
||||
cur += NFileHeader::kNameSize;
|
||||
COPY_STRING_CHECK (cur, item.LinkName, NFileHeader::kNameSize);
|
||||
|
||||
memcpy(cur, item.Magic, 8);
|
||||
cur += 8;
|
||||
|
||||
RETURN_IF_NOT_TRUE(CopyString(cur, item.User, NFileHeader::kUserNameSize));
|
||||
cur += NFileHeader::kUserNameSize;
|
||||
RETURN_IF_NOT_TRUE(CopyString(cur, item.Group, NFileHeader::kGroupNameSize));
|
||||
cur += NFileHeader::kGroupNameSize;
|
||||
COPY_STRING_CHECK (cur, item.User, NFileHeader::kUserNameSize);
|
||||
COPY_STRING_CHECK (cur, item.Group, NFileHeader::kGroupNameSize);
|
||||
|
||||
|
||||
/* temp fix for #202
|
||||
* if (item.DeviceMajorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMajor)); cur += 8;
|
||||
* if (item.DeviceMinorDefined) RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMinor)); cur += 8;
|
||||
*/
|
||||
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMajorDefined ? item.DeviceMajor : 0)); cur += 8;
|
||||
RETURN_IF_NOT_TRUE(WriteOctal_8(cur, item.DeviceMinorDefined ? item.DeviceMinor : 0)); cur += 8;
|
||||
if (item.DeviceMajorDefined)
|
||||
WRITE_OCTAL_8_CHECK (cur, item.DeviceMajor);
|
||||
cur += 8;
|
||||
if (item.DeviceMinorDefined)
|
||||
WRITE_OCTAL_8_CHECK (cur, item.DeviceMinor);
|
||||
cur += 8;
|
||||
|
||||
if (item.IsSparse())
|
||||
{
|
||||
@@ -144,7 +144,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
|
||||
/* we use GNU TAR scheme:
|
||||
checksum field is formatted differently from the
|
||||
other fields: it has [6] digits, a null, then a space. */
|
||||
// RETURN_IF_NOT_TRUE(WriteOctal_8(record + 148, checkSum));
|
||||
// WRITE_OCTAL_8_CHECK(record + 148, checkSum);
|
||||
const unsigned kNumDigits = 6;
|
||||
for (unsigned i = 0; i < kNumDigits; i++)
|
||||
{
|
||||
@@ -176,27 +176,42 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/* OLD_GNU_TAR: writes short name with zero at the end
|
||||
NEW_GNU_TAR: writes short name without zero at the end */
|
||||
|
||||
static const unsigned kNameSize_Max =
|
||||
NFileHeader::kNameSize; // NEW_GNU_TAR / 7-Zip 21.07
|
||||
// NFileHeader::kNameSize - 1; // OLD_GNU_TAR / old 7-Zip
|
||||
|
||||
#define DOES_NAME_FIT_IN_FIELD(name) ((name).Len() <= kNameSize_Max)
|
||||
|
||||
HRESULT COutArchive::WriteHeader(const CItem &item)
|
||||
{
|
||||
unsigned nameSize = item.Name.Len();
|
||||
unsigned linkSize = item.LinkName.Len();
|
||||
|
||||
/* There two versions of GNU tar:
|
||||
OLDGNU_FORMAT: it writes short name and zero at the end
|
||||
GNU_FORMAT: it writes only short name without zero at the end
|
||||
we write it as OLDGNU_FORMAT with zero at the end */
|
||||
|
||||
if (nameSize < NFileHeader::kNameSize &&
|
||||
linkSize < NFileHeader::kNameSize)
|
||||
if (DOES_NAME_FIT_IN_FIELD(item.Name) &&
|
||||
DOES_NAME_FIT_IN_FIELD(item.LinkName))
|
||||
return WriteHeaderReal(item);
|
||||
|
||||
// here we can get all fields from main (item) or create new empty item
|
||||
/*
|
||||
CItem mi;
|
||||
mi.SetDefaultWriteFields();
|
||||
*/
|
||||
|
||||
CItem mi = item;
|
||||
mi.Name = NFileHeader::kLongLink;
|
||||
mi.LinkName.Empty();
|
||||
// SparseBlocks will be ignored by IsSparse()
|
||||
// mi.SparseBlocks.Clear();
|
||||
|
||||
mi.Name = NFileHeader::kLongLink;
|
||||
// 21.07 : we set Mode and MTime props as in GNU TAR:
|
||||
mi.Mode = 0644; // octal
|
||||
mi.MTime = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
const AString *name;
|
||||
// We suppose that GNU tar also writes item for long link before item for LongName?
|
||||
// We suppose that GNU TAR also writes item for long link before item for LongName?
|
||||
if (i == 0)
|
||||
{
|
||||
mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongLink;
|
||||
@@ -207,21 +222,26 @@ HRESULT COutArchive::WriteHeader(const CItem &item)
|
||||
mi.LinkFlag = NFileHeader::NLinkFlag::kGnu_LongName;
|
||||
name = &item.Name;
|
||||
}
|
||||
if (name->Len() < NFileHeader::kNameSize)
|
||||
if (DOES_NAME_FIT_IN_FIELD(*name))
|
||||
continue;
|
||||
unsigned nameStreamSize = name->Len() + 1;
|
||||
// GNU TAR writes null character after NAME to file. We do same here:
|
||||
const unsigned nameStreamSize = name->Len() + 1;
|
||||
mi.PackSize = nameStreamSize;
|
||||
RINOK(WriteHeaderReal(mi));
|
||||
RINOK(WriteBytes((const char *)*name, nameStreamSize));
|
||||
RINOK(WriteBytes(name->Ptr(), nameStreamSize));
|
||||
RINOK(FillDataResidual(nameStreamSize));
|
||||
}
|
||||
|
||||
// 21.07: WriteHeaderReal() writes short part of (Name) and (LinkName).
|
||||
return WriteHeaderReal(item);
|
||||
/*
|
||||
mi = item;
|
||||
if (mi.Name.Len() >= NFileHeader::kNameSize)
|
||||
mi.Name.SetFrom(item.Name, NFileHeader::kNameSize - 1);
|
||||
if (mi.LinkName.Len() >= NFileHeader::kNameSize)
|
||||
mi.LinkName.SetFrom(item.LinkName, NFileHeader::kNameSize - 1);
|
||||
if (!DOES_NAME_FIT_IN_FIELD(mi.Name))
|
||||
mi.Name.SetFrom(item.Name, kNameSize_Max);
|
||||
if (!DOES_NAME_FIT_IN_FIELD(mi.LinkName))
|
||||
mi.LinkName.SetFrom(item.LinkName, kNameSize_Max);
|
||||
return WriteHeaderReal(mi);
|
||||
*/
|
||||
}
|
||||
|
||||
HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
|
||||
@@ -239,7 +259,17 @@ HRESULT COutArchive::WriteFinishHeader()
|
||||
{
|
||||
Byte record[NFileHeader::kRecordSize];
|
||||
memset(record, 0, NFileHeader::kRecordSize);
|
||||
for (unsigned i = 0; i < 2; i++)
|
||||
|
||||
const unsigned kNumFinishRecords = 2;
|
||||
|
||||
/* GNU TAR by default uses --blocking-factor=20 (512 * 20 = 10 KiB)
|
||||
we also can use cluster alignment:
|
||||
const unsigned numBlocks = (unsigned)(Pos / NFileHeader::kRecordSize) + kNumFinishRecords;
|
||||
const unsigned kNumClusterBlocks = (1 << 3); // 8 blocks = 4 KiB
|
||||
const unsigned numFinishRecords = kNumFinishRecords + ((kNumClusterBlocks - numBlocks) & (kNumClusterBlocks - 1));
|
||||
*/
|
||||
|
||||
for (unsigned i = 0; i < kNumFinishRecords; i++)
|
||||
{
|
||||
RINOK(WriteBytes(record, NFileHeader::kRecordSize));
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
|
||||
if (ui.NewProps)
|
||||
{
|
||||
item.SetDefaultWriteFields();
|
||||
item.Mode = ui.Mode;
|
||||
item.Name = ui.Name;
|
||||
item.User = ui.User;
|
||||
@@ -85,11 +86,6 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
|
||||
}
|
||||
|
||||
item.MTime = ui.MTime;
|
||||
item.DeviceMajorDefined = false;
|
||||
item.DeviceMinorDefined = false;
|
||||
item.UID = 0;
|
||||
item.GID = 0;
|
||||
memcpy(item.Magic, NFileHeader::NMagic::kUsTar_00, 8);
|
||||
}
|
||||
else
|
||||
item = inputItems[(unsigned)ui.IndexInArc];
|
||||
|
||||
@@ -403,14 +403,14 @@ STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_table.Free();
|
||||
_phySize = 0;
|
||||
_size = 0;
|
||||
_isArc = false;
|
||||
_unsupported = false;
|
||||
|
||||
for (unsigned i = 0; i < kNumGuids; i++)
|
||||
memset(Guids[i], 0, 16);
|
||||
|
||||
_imgExt = NULL;
|
||||
// CHandlerImg:
|
||||
Clear_HandlerImg_Vars();
|
||||
Stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -226,9 +226,9 @@ class CHandler: public CHandlerImg
|
||||
CByteBuffer BitMap;
|
||||
UInt32 BitMapTag;
|
||||
UInt32 NumUsedBlocks;
|
||||
// CMyComPtr<IInStream> Stream;
|
||||
CMyComPtr<IInStream> ParentStream;
|
||||
CHandler *Parent;
|
||||
UInt64 NumLevels;
|
||||
UString _errorMessage;
|
||||
// bool _unexpectedEnd;
|
||||
|
||||
@@ -604,11 +604,12 @@ enum
|
||||
|
||||
static const CStatProp kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidOffset, VT_UI8},
|
||||
{ NULL, kpidCTime, VT_FILETIME},
|
||||
{ NULL, kpidClusterSize, VT_UI8},
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidNumVolumes, VT_UI4},
|
||||
{ NULL, kpidTotalPhySize, VT_UI8},
|
||||
{ "Parent", kpidParent, VT_BSTR},
|
||||
{ NULL, kpidCreatorApp, VT_BSTR},
|
||||
{ NULL, kpidHostOS, VT_BSTR},
|
||||
@@ -734,6 +735,21 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
case kpidParent: if (NeedParent()) prop = GetParentSequence(); break;
|
||||
case kpidOffset: prop = _startOffset; break;
|
||||
case kpidPhySize: prop = _phySize; break;
|
||||
case kpidTotalPhySize:
|
||||
{
|
||||
const CHandler *p = this;
|
||||
UInt64 sum = 0;
|
||||
do
|
||||
{
|
||||
sum += p->_phySize;
|
||||
p = p->Parent;
|
||||
}
|
||||
while (p);
|
||||
prop = sum;
|
||||
break;
|
||||
}
|
||||
case kpidNumVolumes: if (NumLevels != 1) prop = (UInt32)NumLevels; break;
|
||||
|
||||
/*
|
||||
case kpidErrorFlags:
|
||||
{
|
||||
@@ -762,6 +778,7 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
|
||||
|
||||
RINOK(Open3());
|
||||
|
||||
NumLevels = 1;
|
||||
if (child && memcmp(child->Dyn.ParentId, Footer.Id, 16) != 0)
|
||||
return S_FALSE;
|
||||
if (Footer.Type != kDiskType_Diff)
|
||||
@@ -826,6 +843,10 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
|
||||
// we must show that error code
|
||||
}
|
||||
}
|
||||
if (res == S_OK)
|
||||
{
|
||||
NumLevels = Parent->NumLevels + 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
const CHandler *p = this;
|
||||
@@ -845,16 +866,19 @@ HRESULT CHandler::Open2(IInStream *stream, CHandler *child, IArchiveOpenCallback
|
||||
|
||||
void CHandler::CloseAtError()
|
||||
{
|
||||
// CHandlerImg:
|
||||
Stream.Release();
|
||||
Clear_HandlerImg_Vars();
|
||||
|
||||
_phySize = 0;
|
||||
NumLevels = 0;
|
||||
Bat.Clear();
|
||||
NumUsedBlocks = 0;
|
||||
Parent = NULL;
|
||||
Stream.Release();
|
||||
ParentStream.Release();
|
||||
Dyn.Clear();
|
||||
_errorMessage.Empty();
|
||||
// _unexpectedEnd = false;
|
||||
_imgExt = NULL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
@@ -891,7 +915,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIAN
|
||||
STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **stream)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
*stream = 0;
|
||||
*stream = NULL;
|
||||
if (Footer.IsFixed())
|
||||
{
|
||||
CLimitedInStream *streamSpec = new CLimitedInStream;
|
||||
|
||||
2062
CPP/7zip/Archive/VhdxHandler.cpp
Normal file
2062
CPP/7zip/Archive/VhdxHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1430,7 +1430,6 @@ HRESULT CExtent::Open3(IInStream *stream, IArchiveOpenCallback *openCallback,
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_phySize = 0;
|
||||
_size = 0;
|
||||
|
||||
_cacheCluster = (UInt64)(Int64)-1;
|
||||
_cacheExtent = (unsigned)(int)-1;
|
||||
@@ -1450,8 +1449,10 @@ STDMETHODIMP CHandler::Close()
|
||||
_descriptorBuf.Free();
|
||||
_descriptor.Clear();
|
||||
|
||||
_imgExt = NULL;
|
||||
Stream.Release(); // Stream vriable is unused
|
||||
// CHandlerImg:
|
||||
Clear_HandlerImg_Vars();
|
||||
Stream.Release();
|
||||
|
||||
_extents.Clear();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user