mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 11:14:58 -06:00
302 lines
7.4 KiB
C++
Executable File
302 lines
7.4 KiB
C++
Executable File
// Archive/IsoIn.h
|
||
|
||
#ifndef __ARCHIVE_ISO_IN_H
|
||
#define __ARCHIVE_ISO_IN_H
|
||
|
||
#include "Common/MyCom.h"
|
||
#include "Common/IntToString.h"
|
||
|
||
#include "../../IStream.h"
|
||
|
||
#include "IsoItem.h"
|
||
#include "IsoHeader.h"
|
||
|
||
namespace NArchive {
|
||
namespace NIso {
|
||
|
||
struct CDir: public CDirRecord
|
||
{
|
||
CDir *Parent;
|
||
CObjectVector<CDir> _subItems;
|
||
|
||
void Clear()
|
||
{
|
||
Parent = 0;
|
||
_subItems.Clear();
|
||
}
|
||
|
||
int GetLength(bool checkSusp, int skipSize) const
|
||
{
|
||
int len = GetLengthCur(checkSusp, skipSize);
|
||
if (Parent != 0)
|
||
if (Parent->Parent != 0)
|
||
len += 1 + Parent->GetLength(checkSusp, skipSize);
|
||
return len;
|
||
}
|
||
|
||
int GetLengthU() const
|
||
{
|
||
int len = FileId.GetCapacity() / 2;
|
||
if (Parent != 0)
|
||
if (Parent->Parent != 0)
|
||
len += 1 + Parent->GetLengthU();
|
||
return len;
|
||
}
|
||
|
||
AString GetPath(bool checkSusp, int skipSize) const
|
||
{
|
||
AString s;
|
||
int len = GetLength(checkSusp, skipSize);
|
||
char *p = s.GetBuffer(len + 1);
|
||
p += len;
|
||
*p = 0;
|
||
const CDir *cur = this;
|
||
while(true)
|
||
{
|
||
int curLen = cur->GetLengthCur(checkSusp, skipSize);
|
||
p -= curLen;
|
||
memmove(p, (const char *)(const Byte *)cur->GetNameCur(checkSusp, skipSize), curLen);
|
||
cur = cur->Parent;
|
||
if (cur == 0)
|
||
break;
|
||
if (cur->Parent == 0)
|
||
break;
|
||
p--;
|
||
*p = '\\';
|
||
}
|
||
s.ReleaseBuffer();
|
||
return s;
|
||
}
|
||
|
||
UString GetPathU() const
|
||
{
|
||
UString s;
|
||
int len = GetLengthU();
|
||
wchar_t *p = s.GetBuffer(len + 1);
|
||
p += len;
|
||
*p = 0;
|
||
const CDir *cur = this;
|
||
while(true)
|
||
{
|
||
int curLen = cur->FileId.GetCapacity() / 2;
|
||
p -= curLen;
|
||
for (int 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)b0 << 8) | (wchar_t)b1;
|
||
}
|
||
cur = cur->Parent;
|
||
if (cur == 0)
|
||
break;
|
||
if (cur->Parent == 0)
|
||
break;
|
||
p--;
|
||
*p = L'\\';
|
||
}
|
||
s.ReleaseBuffer();
|
||
return s;
|
||
}
|
||
};
|
||
|
||
struct CDateTime
|
||
{
|
||
UInt16 Year;
|
||
Byte Month;
|
||
Byte Day;
|
||
Byte Hour;
|
||
Byte Minute;
|
||
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; }
|
||
};
|
||
|
||
struct CBootRecordDescriptor
|
||
{
|
||
Byte BootSystemId[32]; // a-characters
|
||
Byte BootId[32]; // a-characters
|
||
Byte BootSystemUse[1977];
|
||
};
|
||
|
||
struct CBootValidationEntry
|
||
{
|
||
Byte PlatformId;
|
||
Byte Id[24]; // to identify the manufacturer/developer of the CD-ROM.
|
||
};
|
||
|
||
struct CBootInitialEntry
|
||
{
|
||
bool Bootable;
|
||
Byte BootMediaType;
|
||
UInt16 LoadSegment;
|
||
/* This is the load segment for the initial boot image. If this
|
||
value is 0 the system will use the traditional segment of 7C0. If this value
|
||
is non-zero the system will use the specified segment. This applies to x86
|
||
architectures only. For "flat" model architectures (such as Motorola) this
|
||
is the address divided by 10. */
|
||
Byte SystemType; // This must be a copy of byte 5 (System Type) from the
|
||
// Partition Table found in the boot image.
|
||
UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
|
||
// will store at Load Segment during the initial boot procedure.
|
||
UInt32 LoadRBA; // This is the start address of the virtual disk. CD<43>s use
|
||
// Relative/Logical block addressing.
|
||
|
||
UInt64 GetSize() const
|
||
{
|
||
// if (BootMediaType == NBootMediaType::k1d44Floppy) (1440 << 10);
|
||
return SectorCount * 512;
|
||
}
|
||
|
||
UString GetName() const
|
||
{
|
||
UString s;
|
||
if (Bootable)
|
||
s += L"Bootable";
|
||
else
|
||
s += L"NotBootable";
|
||
s += L"_";
|
||
if (BootMediaType >= kNumBootMediaTypes)
|
||
{
|
||
wchar_t name[32];
|
||
ConvertUInt64ToString(BootMediaType, name);
|
||
s += name;
|
||
}
|
||
else
|
||
s += kMediaTypes[BootMediaType];
|
||
s += L".img";
|
||
return s;
|
||
}
|
||
};
|
||
|
||
struct CVolumeDescriptor
|
||
{
|
||
Byte VolFlags;
|
||
Byte SystemId[32]; // a-characters. An identification of a system
|
||
// which can recognize and act upon the content of the Logical
|
||
// Sectors with logical Sector Numbers 0 to 15 of the volume.
|
||
Byte VolumeId[32]; // d-characters. An identification of the volume.
|
||
UInt32 VolumeSpaceSize; // the number of Logical Blocks in which the Volume Space of the volume is recorded
|
||
Byte EscapeSequence[32];
|
||
UInt16 VolumeSetSize;
|
||
UInt16 VolumeSequenceNumber; // the ordinal number of the volume in the Volume Set of which the volume is a member.
|
||
UInt16 LogicalBlockSize;
|
||
UInt32 PathTableSize;
|
||
UInt32 LPathTableLocation;
|
||
UInt32 LOptionalPathTableLocation;
|
||
UInt32 MPathTableLocation;
|
||
UInt32 MOptionalPathTableLocation;
|
||
CDirRecord RootDirRecord;
|
||
Byte VolumeSetId[128];
|
||
Byte PublisherId[128];
|
||
Byte DataPreparerId[128];
|
||
Byte ApplicationId[128];
|
||
Byte CopyrightFileId[37];
|
||
Byte AbstractFileId[37];
|
||
Byte BibFileId[37];
|
||
CDateTime CreationTime;
|
||
CDateTime ModificationTime;
|
||
CDateTime ExpirationTime;
|
||
CDateTime EffectiveTime;
|
||
Byte FileStructureVersion; // = 1;
|
||
Byte ApplicationUse[512];
|
||
|
||
bool IsJoliet() const
|
||
{
|
||
if ((VolFlags & 1) != 0)
|
||
return false;
|
||
Byte b = EscapeSequence[2];
|
||
return (EscapeSequence[0] == 0x25 && EscapeSequence[1] == 0x2F &&
|
||
(b == 0x40 || b == 0x43 || b == 0x45));
|
||
}
|
||
};
|
||
|
||
struct CRef
|
||
{
|
||
CDir *Dir;
|
||
UInt32 Index;
|
||
};
|
||
|
||
const UInt32 kBlockSize = 1 << 11;
|
||
|
||
class CInArchive
|
||
{
|
||
CMyComPtr<IInStream> _stream;
|
||
UInt64 _position;
|
||
|
||
Byte m_Buffer[kBlockSize];
|
||
UInt32 m_BufferPos;
|
||
|
||
CDir _rootDir;
|
||
bool _bootIsDefined;
|
||
CBootRecordDescriptor _bootDesc;
|
||
|
||
HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
|
||
void Skeep(size_t size);
|
||
void SkeepZeros(size_t size);
|
||
Byte ReadByte();
|
||
void ReadBytes(Byte *data, UInt32 size);
|
||
UInt16 ReadUInt16Spec();
|
||
UInt16 ReadUInt16();
|
||
UInt32 ReadUInt32Le();
|
||
UInt32 ReadUInt32Be();
|
||
UInt32 ReadUInt32();
|
||
UInt64 ReadUInt64();
|
||
UInt32 ReadDigits(int numDigits);
|
||
void ReadDateTime(CDateTime &d);
|
||
void ReadRecordingDateTime(CRecordingDateTime &t);
|
||
void ReadDirRecord2(CDirRecord &r, Byte len);
|
||
void ReadDirRecord(CDirRecord &r);
|
||
|
||
void ReadBootRecordDescriptor(CBootRecordDescriptor &d);
|
||
void ReadVolumeDescriptor(CVolumeDescriptor &d);
|
||
|
||
void SeekToBlock(UInt32 blockIndex);
|
||
void ReadDir(CDir &d, int level);
|
||
void CreateRefs(CDir &d);
|
||
|
||
void ReadBootInfo();
|
||
HRESULT Open2();
|
||
public:
|
||
HRESULT Open(IInStream *inStream);
|
||
void Clear();
|
||
|
||
UInt64 _archiveSize;
|
||
|
||
CRecordVector<CRef> Refs;
|
||
CObjectVector<CVolumeDescriptor> VolDescs;
|
||
int MainVolDescIndex;
|
||
UInt32 BlockSize;
|
||
CObjectVector<CBootInitialEntry> BootEntries;
|
||
|
||
|
||
bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
|
||
|
||
UInt64 GetBootItemSize(int index) const
|
||
{
|
||
const CBootInitialEntry &be = BootEntries[index];
|
||
UInt64 size = be.GetSize();
|
||
if (be.BootMediaType == NBootMediaType::k1d2Floppy)
|
||
size = (1200 << 10);
|
||
else if (be.BootMediaType == NBootMediaType::k1d44Floppy)
|
||
size = (1440 << 10);
|
||
else if (be.BootMediaType == NBootMediaType::k2d88Floppy)
|
||
size = (2880 << 10);
|
||
UInt64 startPos = be.LoadRBA * BlockSize;
|
||
if (startPos < _archiveSize)
|
||
{
|
||
if (_archiveSize - startPos < size)
|
||
size = _archiveSize - startPos;
|
||
}
|
||
return size;
|
||
}
|
||
|
||
bool IsSusp;
|
||
int SuspSkipSize;
|
||
};
|
||
|
||
}}
|
||
|
||
#endif
|