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

@@ -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
}

View File

@@ -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"
};
}}

View File

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

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

View File

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

View File

@@ -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;
}

View File

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