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:
Diffstat (limited to 'CPP/7zip/Archive/Iso/IsoIn.cpp')
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.cpp193
1 files changed, 151 insertions, 42 deletions
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()