Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2015-06-15 03:00:00 +0300
committerKornel Lesiński <kornel@geekhood.net>2016-05-28 02:16:54 +0300
commit54490d51d5c6b0d794dcbad2d634d4c95fc25b6c (patch)
treec3c413656432c0ef87b2841c80e42b55ad17d4e8 /CPP/7zip/Archive/Iso
parent0713a3ab803e57401f18432148b4139e5fe6e5dd (diff)
15.0515.05
Diffstat (limited to 'CPP/7zip/Archive/Iso')
-rw-r--r--CPP/7zip/Archive/Iso/IsoHandler.cpp37
-rw-r--r--CPP/7zip/Archive/Iso/IsoHeader.cpp9
-rw-r--r--CPP/7zip/Archive/Iso/IsoHeader.h8
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.cpp193
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.h132
-rw-r--r--CPP/7zip/Archive/Iso/IsoItem.h33
-rw-r--r--CPP/7zip/Archive/Iso/IsoRegister.cpp12
7 files changed, 263 insertions, 161 deletions
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index aef920b0..713764d9 100644
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -79,8 +79,7 @@ static void AddString(AString &s, const char *name, const Byte *p, unsigned size
if (i != 0)
{
AString d;
- memcpy(d.GetBuffer(i), p, i);
- d.ReleaseBuffer(i);
+ d.SetFrom((const char *)p, i);
s += '\n';
s += name;
s += ": ";
@@ -170,11 +169,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- // char name[16];
- // ConvertUInt32ToString(index + 1, name);
AString s = "[BOOT]" STRING_PATH_SEPARATOR;
- // s += name;
- // s += '-';
+ if (_archive.BootEntries.Size() != 1)
+ {
+ char temp[16];
+ ConvertUInt32ToString(index + 1, temp);
+ s += temp;
+ s += '-';
+ }
s += be.GetName();
prop = s;
break;
@@ -197,18 +199,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
UString s;
if (_archive.IsJoliet())
- s = item.GetPathU();
+ item.GetPathU(s);
else
s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);
- int pos = s.ReverseFind(L';');
- if (pos >= 0 && pos == (int)s.Len() - 2)
- if (s.Back() == L'1')
- s.DeleteFrom(pos);
- if (!s.IsEmpty())
- if (s.Back() == L'.')
- s.DeleteBack();
- prop = (const wchar_t *)NItemName::GetOSName2(s);
+ if (s.Len() >= 2 && s[s.Len() - 2] == ';' && s.Back() == '1')
+ s.DeleteFrom(s.Len() - 2);
+
+ if (!s.IsEmpty() && s.Back() == L'.')
+ s.DeleteBack();
+
+ NItemName::ConvertToOSName2(s);
+ prop = s;
}
break;
case kpidIsDir: prop = item.IsDir(); break;
@@ -319,8 +321,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 offset = 0;
for (UInt32 e = 0; e < ref.NumExtents; e++)
{
- if (e != 0)
- lps->InSize = lps->OutSize = currentTotalSize + offset;
+ lps->InSize = lps->OutSize = currentTotalSize + offset;
const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * _archive.BlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(item2.Size);
@@ -356,6 +357,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
*stream = 0;
UInt64 blockIndex;
UInt64 currentItemSize;
+
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
@@ -402,6 +404,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
currentItemSize = _archive.GetBootItemSize(bootIndex);
blockIndex = be.LoadRBA;
}
+
return CreateLimitedInStream(_stream, blockIndex * _archive.BlockSize, currentItemSize, stream);
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.cpp b/CPP/7zip/Archive/Iso/IsoHeader.cpp
index 1cd2516c..59c283c1 100644
--- a/CPP/7zip/Archive/Iso/IsoHeader.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHeader.cpp
@@ -9,13 +9,4 @@ namespace NIso {
const char *kElToritoSpec = "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0";
-const char *kMediaTypes[5] =
-{
- "NoEmulation"
- , "1.2M"
- , "1.44M"
- , "2.88M"
- , "HardDisk"
-};
-
}}
diff --git a/CPP/7zip/Archive/Iso/IsoHeader.h b/CPP/7zip/Archive/Iso/IsoHeader.h
index ce21b0ff..db0b1df9 100644
--- a/CPP/7zip/Archive/Iso/IsoHeader.h
+++ b/CPP/7zip/Archive/Iso/IsoHeader.h
@@ -34,6 +34,11 @@ namespace NBootEntryId
const Byte kValidationEntry = 1;
const Byte kInitialEntryNotBootable = 0;
const Byte kInitialEntryBootable = 0x88;
+
+ const Byte kMoreHeaders = 0x90;
+ const Byte kFinalHeader = 0x91;
+
+ const Byte kExtensionIndicator = 0x44;
}
namespace NBootPlatformId
@@ -54,9 +59,6 @@ namespace NBootMediaType
const Byte kHardDisk = 4;
}
-const unsigned kNumBootMediaTypes = 5;
-extern const char *kMediaTypes[];
-
}}
#endif
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index ba12acae..b72e8687 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/CpuArch.h"
+
#include "../../../Common/MyException.h"
#include "../../Common/StreamUtils.h"
@@ -10,11 +12,78 @@
namespace NArchive {
namespace NIso {
-
+
struct CUnexpectedEndException {};
struct CHeaderErrorException {};
struct CEndianErrorException {};
+static const char * const kMediaTypes[] =
+{
+ "NoEmul"
+ , "1.2M"
+ , "1.44M"
+ , "2.88M"
+ , "HardDisk"
+};
+
+bool CBootInitialEntry::Parse(const Byte *p)
+{
+ Bootable = (p[0] == NBootEntryId::kInitialEntryBootable);
+ BootMediaType = p[1];
+ LoadSegment = GetUi16(p + 2);
+ SystemType = p[4];
+ SectorCount = GetUi16(p + 6);
+ LoadRBA = GetUi32(p + 8);
+ memcpy(VendorSpec, p + 12, 20);
+ if (p[5] != 0)
+ return false;
+ if (p[0] != NBootEntryId::kInitialEntryBootable
+ && p[0] != NBootEntryId::kInitialEntryNotBootable)
+ return false;
+ return true;
+}
+
+AString CBootInitialEntry::GetName() const
+{
+ AString s = (Bootable ? "Boot" : "NotBoot");
+ s += '-';
+
+ if (BootMediaType < ARRAY_SIZE(kMediaTypes))
+ s += kMediaTypes[BootMediaType];
+ else
+ {
+ char name[16];
+ ConvertUInt32ToString(BootMediaType, name);
+ s += name;
+ }
+
+ if (VendorSpec[0] == 1)
+ {
+ // "Language and Version Information (IBM)"
+
+ unsigned i;
+ for (i = 1; i < sizeof(VendorSpec); i++)
+ if (VendorSpec[i] > 0x7F)
+ break;
+ if (i == sizeof(VendorSpec))
+ {
+ s += '-';
+ for (i = 1; i < sizeof(VendorSpec); i++)
+ {
+ char c = VendorSpec[i];
+ if (c == 0)
+ break;
+ if (c == '\\' || c == '/')
+ c = '_';
+ s += c;
+ }
+ }
+ }
+
+ s += ".img";
+ return s;
+}
+
Byte CInArchive::ReadByte()
{
if (m_BufferPos >= BlockSize)
@@ -58,15 +127,6 @@ void CInArchive::SkipZeros(size_t size)
}
}
-UInt16 CInArchive::ReadUInt16Spec()
-{
- UInt16 val = 0;
- for (int i = 0; i < 2; i++)
- val |= ((UInt16)(ReadByte()) << (8 * i));
- return val;
-}
-
-
UInt16 CInArchive::ReadUInt16()
{
Byte b[4];
@@ -179,15 +239,15 @@ void CInArchive::ReadDirRecord2(CDirRecord &r, Byte len)
Byte idLen = ReadByte();
r.FileId.Alloc(idLen);
ReadBytes((Byte *)r.FileId, idLen);
- int padSize = 1 - (idLen & 1);
+ unsigned padSize = 1 - (idLen & 1);
- // SkipZeros(1 - (idLen & 1));
- Skip(1 - (idLen & 1)); // it's bug in some cd's. Must be zeros
+ // SkipZeros(padSize);
+ Skip(padSize); // it's bug in some cd's. Must be zeros
- int curPos = 33 + idLen + padSize;
+ unsigned curPos = 33 + idLen + padSize;
if (curPos > len)
throw CHeaderErrorException();
- int rem = len - curPos;
+ unsigned rem = len - curPos;
r.SystemUse.Alloc(rem);
ReadBytes((Byte *)r.SystemUse, rem);
}
@@ -349,45 +409,94 @@ void CInArchive::ReadBootInfo()
{
if (!_bootIsDefined)
return;
+ HeadersError = true;
+
if (memcmp(_bootDesc.BootSystemId, kElToritoSpec, sizeof(_bootDesc.BootSystemId)) != 0)
return;
- const Byte *p = (const Byte *)_bootDesc.BootSystemUse;
- UInt32 blockIndex = p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24);
+ UInt32 blockIndex = GetUi32(_bootDesc.BootSystemUse);
SeekToBlock(blockIndex);
- Byte b = ReadByte();
- if (b != NBootEntryId::kValidationEntry)
+
+ Byte buf[32];
+ ReadBytes(buf, 32);
+
+ if (buf[0] != NBootEntryId::kValidationEntry
+ || buf[2] != 0
+ || buf[3] != 0
+ || buf[30] != 0x55
+ || buf[31] != 0xAA)
return;
+
{
+ UInt32 sum = 0;
+ for (unsigned i = 0; i < 32; i += 2)
+ sum += GetUi16(buf + i);
+ if ((sum & 0xFFFF) != 0)
+ return;
+ /*
CBootValidationEntry e;
- e.PlatformId = ReadByte();
- if (ReadUInt16Spec() != 0)
- throw CHeaderErrorException();
- ReadBytes(e.Id, sizeof(e.Id));
- /* UInt16 checkSum = */ ReadUInt16Spec();
- if (ReadByte() != 0x55)
- throw CHeaderErrorException();
- if (ReadByte() != 0xAA)
- throw CHeaderErrorException();
+ e.PlatformId = buf[1];
+ memcpy(e.Id, buf + 4, sizeof(e.Id));
+ // UInt16 checkSum = GetUi16(p + 28);
+ */
}
- b = ReadByte();
- if (b == NBootEntryId::kInitialEntryBootable || b == NBootEntryId::kInitialEntryNotBootable)
+
+ ReadBytes(buf, 32);
{
CBootInitialEntry e;
- e.Bootable = (b == NBootEntryId::kInitialEntryBootable);
- e.BootMediaType = ReadByte();
- e.LoadSegment = ReadUInt16Spec();
- e.SystemType = ReadByte();
- if (ReadByte() != 0)
- throw CHeaderErrorException();
- e.SectorCount = ReadUInt16Spec();
- e.LoadRBA = ReadUInt32Le();
- if (ReadByte() != 0)
- throw CHeaderErrorException();
+ if (!e.Parse(buf))
+ return;
BootEntries.Add(e);
}
- else
- return;
+
+ bool error = false;
+
+ for (;;)
+ {
+ ReadBytes(buf, 32);
+ Byte headerIndicator = buf[0];
+ if (headerIndicator != NBootEntryId::kMoreHeaders
+ && headerIndicator != NBootEntryId::kFinalHeader)
+ break;
+
+ // Section Header
+ // Byte platform = p[1];
+ unsigned numEntries = GetUi16(buf + 2);
+ // id[28]
+
+ for (unsigned i = 0; i < numEntries; i++)
+ {
+ ReadBytes(buf, 32);
+ CBootInitialEntry e;
+ if (!e.Parse(buf))
+ {
+ error = true;
+ break;
+ }
+ if (e.BootMediaType & (1 << 5))
+ {
+ // Section entry extension
+ for (unsigned j = 0;; j++)
+ {
+ ReadBytes(buf, 32);
+ if (j > 32 || buf[0] != NBootEntryId::kExtensionIndicator)
+ {
+ error = true;
+ break;
+ }
+ if ((buf[1] & (1 << 5)) == 0)
+ break;
+ // info += (buf + 2, 30)
+ }
+ }
+ BootEntries.Add(e);
+ }
+
+ if (headerIndicator != NBootEntryId::kMoreHeaders)
+ break;
+ }
+
+ HeadersError = error;
}
HRESULT CInArchive::Open2()
diff --git a/CPP/7zip/Archive/Iso/IsoIn.h b/CPP/7zip/Archive/Iso/IsoIn.h
index 614b3744..c2007bce 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.h
+++ b/CPP/7zip/Archive/Iso/IsoIn.h
@@ -25,77 +25,92 @@ struct CDir: public CDirRecord
_subItems.Clear();
}
- unsigned GetLen(bool checkSusp, unsigned skipSize) const
- {
- unsigned len = GetLenCur(checkSusp, skipSize);
- if (Parent != 0)
- if (Parent->Parent != 0)
- len += 1 + Parent->GetLen(checkSusp, skipSize);
- return len;
- }
-
- unsigned GetLenU() const
- {
- unsigned len = (unsigned)(FileId.Size() / 2);
- if (Parent != 0)
- if (Parent->Parent != 0)
- len += 1 + Parent->GetLenU();
- return len;
- }
-
AString GetPath(bool checkSusp, unsigned skipSize) const
{
AString s;
- unsigned len = GetLen(checkSusp, skipSize);
- char *p = s.GetBuffer(len);
- p += len;
- *p = 0;
+
+ unsigned len = 0;
const CDir *cur = this;
+
for (;;)
{
- unsigned curLen = cur->GetLenCur(checkSusp, skipSize);
- p -= curLen;
- memcpy(p, (const char *)(const Byte *)cur->GetNameCur(checkSusp, skipSize), curLen);
+ unsigned curLen;
+ cur->GetNameCur(checkSusp, skipSize, curLen);
+ len += curLen;
cur = cur->Parent;
- if (cur == 0)
+ if (!cur || !cur->Parent)
break;
- if (cur->Parent == 0)
+ len++;
+ }
+
+ char *p = s.GetBuf_SetEnd(len) + len;
+
+ cur = this;
+
+ for (;;)
+ {
+ unsigned curLen;
+ const Byte *name = cur->GetNameCur(checkSusp, skipSize, curLen);
+ p -= curLen;
+ if (curLen != 0)
+ memcpy(p, name, curLen);
+ cur = cur->Parent;
+ if (!cur || !cur->Parent)
break;
p--;
*p = CHAR_PATH_SEPARATOR;
}
- s.ReleaseBuffer();
+
return s;
}
- UString GetPathU() const
+ void GetPathU(UString &s) const
{
- UString s;
- unsigned len = GetLenU();
- wchar_t *p = s.GetBuffer(len);
- p += len;
- *p = 0;
+ s.Empty();
+
+ unsigned len = 0;
const CDir *cur = this;
+
for (;;)
{
unsigned curLen = (unsigned)(cur->FileId.Size() / 2);
- p -= curLen;
- for (unsigned i = 0; i < curLen; i++)
- {
- Byte b0 = ((const Byte *)cur->FileId)[i * 2];
- Byte b1 = ((const Byte *)cur->FileId)[i * 2 + 1];
- p[i] = (wchar_t)(((wchar_t)b0 << 8) | b1);
- }
+ const Byte *fid = cur->FileId;
+
+ unsigned i;
+ for (i = 0; i < curLen; i++)
+ if (fid[i * 2] == 0 && fid[i * 2 + 1] == 0)
+ break;
+ len += i;
cur = cur->Parent;
- if (cur == 0)
+ if (!cur || !cur->Parent)
break;
- if (cur->Parent == 0)
+ len++;
+ }
+
+ wchar_t *p = s.GetBuf_SetEnd(len) + len;
+
+ cur = this;
+
+ for (;;)
+ {
+ unsigned curLen = (unsigned)(cur->FileId.Size() / 2);
+ const Byte *fid = cur->FileId;
+
+ unsigned i;
+ for (i = 0; i < curLen; i++)
+ if (fid[i * 2] == 0 && fid[i * 2 + 1] == 0)
+ break;
+ curLen = i;
+
+ p -= curLen;
+ for (i = 0; i < curLen; i++)
+ p[i] = (wchar_t)(((wchar_t)fid[i * 2] << 8) | fid[i * 2 + 1]);
+ cur = cur->Parent;
+ if (!cur || !cur->Parent)
break;
p--;
*p = WCHAR_PATH_SEPARATOR;
}
- s.ReleaseBuffer();
- return s;
}
};
@@ -109,6 +124,7 @@ struct CDateTime
Byte Second;
Byte Hundredths;
signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
+
bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; }
@@ -118,7 +134,7 @@ struct CDateTime
bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, value);
if (res)
{
- value -= (UInt64)((Int64)GmtOffset * 15 * 60);
+ value -= (Int64)((Int32)GmtOffset * 15 * 60);
value *= 10000000;
}
ft.dwLowDateTime = (DWORD)value;
@@ -157,27 +173,16 @@ struct CBootInitialEntry
UInt32 LoadRBA; // This is the start address of the virtual disk. CD’s use
// Relative/Logical block addressing.
- UInt64 GetSize() const
+ Byte VendorSpec[20];
+
+ UInt32 GetSize() const
{
// if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10);
- return SectorCount * 512;
+ return (UInt32)SectorCount * 512;
}
- AString GetName() const
- {
- AString s = (Bootable ? "Bootable" : "NotBootable");
- s += '_';
- if (BootMediaType < kNumBootMediaTypes)
- s += kMediaTypes[BootMediaType];
- else
- {
- char name[16];
- ConvertUInt32ToString(BootMediaType, name);
- s += name;
- }
- s += ".img";
- return s;
- }
+ bool Parse(const Byte *p);
+ AString GetName() const;
};
struct CVolumeDescriptor
@@ -247,7 +252,6 @@ class CInArchive
void SkipZeros(size_t size);
Byte ReadByte();
void ReadBytes(Byte *data, UInt32 size);
- UInt16 ReadUInt16Spec();
UInt16 ReadUInt16();
UInt32 ReadUInt32Le();
UInt32 ReadUInt32Be();
diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h
index b6ae21b7..2603afdb 100644
--- a/CPP/7zip/Archive/Iso/IsoItem.h
+++ b/CPP/7zip/Archive/Iso/IsoItem.h
@@ -29,7 +29,7 @@ struct CRecordingDateTime
bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, value);
if (res)
{
- value -= (UInt64)((Int64)GmtOffset * 15 * 60);
+ value -= (Int64)((Int32)GmtOffset * 15 * 60);
value *= 10000000;
}
ft.dwLowDateTime = (DWORD)value;
@@ -94,28 +94,23 @@ struct CDirRecord
return 0;
}
- unsigned GetLenCur(bool checkSusp, int skipSize) const
+ const Byte* GetNameCur(bool checkSusp, int skipSize, unsigned &nameLenRes) const
{
+ const Byte *res = NULL;
+ unsigned len = 0;
if (checkSusp)
+ res = FindSuspName(skipSize, len);
+ if (!res)
{
- unsigned len;
- const Byte *res = FindSuspName(skipSize, len);
- if (res != 0)
- return len;
+ res = (const Byte *)FileId;
+ len = (unsigned)FileId.Size();
}
- return (unsigned)FileId.Size();
- }
-
- const Byte* GetNameCur(bool checkSusp, int skipSize) const
- {
- if (checkSusp)
- {
- unsigned len;
- const Byte *res = FindSuspName(skipSize, len);
- if (res != 0)
- return res;
- }
- return (const Byte *)FileId;
+ unsigned i;
+ for (i = 0; i < len; i++)
+ if (res[i] == 0)
+ break;
+ nameLenRes = i;
+ return res;
}
diff --git a/CPP/7zip/Archive/Iso/IsoRegister.cpp b/CPP/7zip/Archive/Iso/IsoRegister.cpp
index c6f4a521..0205238d 100644
--- a/CPP/7zip/Archive/Iso/IsoRegister.cpp
+++ b/CPP/7zip/Archive/Iso/IsoRegister.cpp
@@ -9,15 +9,13 @@
namespace NArchive {
namespace NIso {
-IMP_CreateArcIn
+static const Byte k_Signature[] = { 'C', 'D', '0', '0', '1' };
-static CArcInfo g_ArcInfo =
- { "Iso", "iso img", 0, 0xE7,
- 5, { 'C', 'D', '0', '0', '1' },
+REGISTER_ARC_I(
+ "Iso", "iso img", 0, 0xE7,
+ k_Signature,
NArchive::NIso::kStartPos + 1,
0,
- CreateArc };
-
-REGISTER_ARC(Iso)
+ NULL)
}}