From f0c4c649259fa5c006bcbe11fad1147cd619ad99 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Tue, 31 Dec 2024 17:40:27 -0600 Subject: [PATCH] iso9660: add VolumeParser --- filesystem/iso9660/ByteParser.java | 19 ++-- filesystem/iso9660/DirectoryRecord.java | 28 +++-- .../iso9660/PrimaryVolumeDescriptor.java | 2 +- filesystem/iso9660/VolumeParser.java | 106 ++++++++++++++++++ p/ISOParser.java | 19 ---- 5 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 filesystem/iso9660/VolumeParser.java delete mode 100644 p/ISOParser.java diff --git a/filesystem/iso9660/ByteParser.java b/filesystem/iso9660/ByteParser.java index 4adc7fd..ccc4fd3 100644 --- a/filesystem/iso9660/ByteParser.java +++ b/filesystem/iso9660/ByteParser.java @@ -2,7 +2,7 @@ package filesystem.iso9660; public class ByteParser { byte[] array; - int offset; + public int offset; public ByteParser(byte[] array, int offset) { this.array = array; @@ -11,7 +11,7 @@ public class ByteParser { public static int shortLE(int i0, int i1) { return ((i1 << 8) - | (i0 << 0)); + | (i0 << 0)) & 0xffff; } public static int intLE(int i0, int i1, int i2, int i3) { @@ -22,21 +22,22 @@ public class ByteParser { } public int getByte(int pos) { - return array[offset + pos]; + int i0 = array[offset + pos] & 0xff; + return i0; } public int getShortLE(int pos) { - int i0 = array[offset + pos + 0]; - int i1 = array[offset + pos + 1]; + int i0 = array[offset + pos + 0] & 0xff; + int i1 = array[offset + pos + 1] & 0xff; return shortLE(i0, i1); } public int getIntLE(int pos) { - int i0 = array[offset + pos + 0]; - int i1 = array[offset + pos + 1]; - int i2 = array[offset + pos + 2]; - int i3 = array[offset + pos + 3]; + int i0 = array[offset + pos + 0] & 0xff; + int i1 = array[offset + pos + 1] & 0xff; + int i2 = array[offset + pos + 2] & 0xff; + int i3 = array[offset + pos + 3] & 0xff; return intLE(i0, i1, i2, i3); } diff --git a/filesystem/iso9660/DirectoryRecord.java b/filesystem/iso9660/DirectoryRecord.java index 6e8409f..9994ad3 100644 --- a/filesystem/iso9660/DirectoryRecord.java +++ b/filesystem/iso9660/DirectoryRecord.java @@ -23,28 +23,34 @@ public class DirectoryRecord extends ByteParser { public static final int LENGTH_OF_FILE_IDENTIFIER_END = 32; public static final int FILE_IDENTIFIER_START = 33; public static final int FILE_IDENTIFIER_END = 32; - public static final int lengthOfDirectoryRecord() { + public DirectoryRecord(byte[] array, int offset) { + super(array, offset); + } + public int lengthOfDirectoryRecord() { return getByte(LENGTH_OF_DIRECTORY_RECORD_START); } - public static final int extendedAttributeRecordLength() { + public int extendedAttributeRecordLength() { return getByte(EXTENDED_ATTRIBUTE_RECORD_LENGTH_START); } - public static final int locationOfExtent() { - return getIntBE(LOCATION_OF_EXTENT_START); + public int locationOfExtent() { + return getIntLE(LOCATION_OF_EXTENT_START); } - public static final int dataLength() { - return getIntBE(DATA_LENGTH_START); + public int dataLength() { + return getIntLE(DATA_LENGTH_START); } - public static final int fileUnitSize() { + public int fileFlags() { + return getByte(FILE_FLAGS_START); + } + public int fileUnitSize() { return getByte(FILE_UNIT_SIZE_START); } - public static final int interleaveGapSize() { + public int interleaveGapSize() { return getByte(INTERLEAVE_GAP_SIZE_START); } - public static final int volumeSequenceNumber() { - return getShortBE(VOLUME_SEQUENCE_NUMBER_START); + public int volumeSequenceNumber() { + return getShortLE(VOLUME_SEQUENCE_NUMBER_START); } - public static final int lengthOfFileIdentifier() { + public int lengthOfFileIdentifier() { return getByte(LENGTH_OF_FILE_IDENTIFIER_START); } } diff --git a/filesystem/iso9660/PrimaryVolumeDescriptor.java b/filesystem/iso9660/PrimaryVolumeDescriptor.java index 72768e3..5faa6f2 100644 --- a/filesystem/iso9660/PrimaryVolumeDescriptor.java +++ b/filesystem/iso9660/PrimaryVolumeDescriptor.java @@ -57,7 +57,7 @@ public class PrimaryVolumeDescriptor extends ByteParser { public static final int FILE_STRUCTURE_VERSION_END = 881; public static final int APPLICATION_USE_START = 883; public static final int APPLICATION_USE_END = 1394; - PrimaryVolumeDescriptor(byte[] array, int offset) { + public PrimaryVolumeDescriptor(byte[] array, int offset) { super(array, offset); } public int volumeDescriptorType() { diff --git a/filesystem/iso9660/VolumeParser.java b/filesystem/iso9660/VolumeParser.java new file mode 100644 index 0000000..804fd4d --- /dev/null +++ b/filesystem/iso9660/VolumeParser.java @@ -0,0 +1,106 @@ +package p; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.io.IOException; + +import filesystem.iso9660.PrimaryVolumeDescriptor; +import filesystem.iso9660.DirectoryRecord; + +class ISOParser { + byte[] buf; + DirectoryRecord dr; + + static final int FILE_FLAGS__DIRECTORY = 2; + + public static void printIdentifier(byte[] buf, int offset, int start, int length) { + for (int i = 0; i < length; i++) { + System.out.print((char)buf[offset + start + i]); + } + } + + public boolean drIsSelfOrParent() { + if (dr.lengthOfFileIdentifier() != 1) { + return false; + } + byte start = buf[DirectoryRecord.FILE_IDENTIFIER_START]; + return (start == 0 || start == 1); + } + + public void walkDirectory(int extent, int num_extents, int indent) { + int[] child_extents = new int[64]; + int[] child_lengths = new int[64]; + int child_ix = 0; + + while (num_extents > 0) { + int offset = extent * 2048; + while (true) { + dr.offset = offset; + if (dr.lengthOfDirectoryRecord() == 0) { + System.out.print("break\n"); + break; + } + + if (!drIsSelfOrParent()) { + for (int i = 0; i < indent; i++) + System.out.print(" "); + + System.out.print("offset: "); + System.out.print(dr.offset); + + System.out.print("; file_flags: "); + System.out.print((int)dr.fileFlags()); + + if ((dr.fileFlags() & FILE_FLAGS__DIRECTORY) == 0) { + System.out.print(" [regular file] "); + //dr.locationOfExtent(); + //dr.dataLength(); + } else { + System.out.print(" [directory] "); + child_extents[child_ix] = dr.locationOfExtent(); + child_lengths[child_ix] = dr.dataLength(); + child_ix += 1; + } + + System.out.print("; file_identifier: "); + printIdentifier(buf, offset, DirectoryRecord.FILE_IDENTIFIER_START, dr.lengthOfFileIdentifier()); + System.out.println(); + } + + offset += dr.lengthOfDirectoryRecord(); + } + num_extents -= 1; + extent += 1; + } + + for (int i = 0; i < child_ix; i++) { + int child_extent = child_extents[i]; + int child_num_extents = child_lengths[i] >> 11; // division by 2048 + walkDirectory(child_extent, child_num_extents, indent + 1); + } + } + + public static void main(String[] args) throws IOException { + ISOParser parser = new ISOParser(); + parser.buf = Files.readAllBytes(Paths.get("classes.iso")); + + int pvd_offset = 2048 * 16; + + System.out.print("standard identifier: "); + for (int i = PrimaryVolumeDescriptor.STANDARD_IDENTIFIER_START; i <= PrimaryVolumeDescriptor.STANDARD_IDENTIFIER_END; i++) { + System.out.print((char)parser.buf[pvd_offset + i]); + } + System.out.println(); + + + int directory_record_for_root_directory = pvd_offset + PrimaryVolumeDescriptor.DIRECTORY_RECORD_FOR_ROOT_DIRECTORY_START; + System.out.println("root directory record: "); + parser.dr = new DirectoryRecord(parser.buf, directory_record_for_root_directory); + System.out.println(parser.dr.locationOfExtent()); + System.out.println(parser.dr.dataLength()); + + int extent = parser.dr.locationOfExtent(); + int num_extents = parser.dr.dataLength() >> 11; // division by 2048 + parser.walkDirectory(extent, num_extents, 0); + } +} diff --git a/p/ISOParser.java b/p/ISOParser.java deleted file mode 100644 index 5a1a046..0000000 --- a/p/ISOParser.java +++ /dev/null @@ -1,19 +0,0 @@ -package p; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.io.IOException; - -import filesystem.iso9660.PrimaryVolumeDescriptor; - -class ISOParser { - public static void main(String[] args) throws IOException { - byte[] buf = Files.readAllBytes(Paths.get("test.iso")); - - for (int i = PrimaryVolumeDescriptor.STANDARD_IDENTIFIER_START; i <= PrimaryVolumeDescriptor.STANDARD_IDENTIFIER_END; i++) { - System.out.print(buf[i]); - } - System.out.println(); - - } -}