This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions

View File

@@ -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()