import sys, os, struct, re, csv re_name = re.compile(r"(.*);([0-9]+)") block_size = 2352 def readSectorForm1(f, lba, count): f.seek(lba * block_size) data = "" for i in xrange(count): block = f.read(block_size) data += block[24:2048+24] del block return data def readDir( f, path, dir_pos, dir_size, parent): dir = readSectorForm1(f, dir_pos, (dir_size + 2047) / 2048) list = [] pos = 0 while pos < len(dir): (entry_size, file_pos, file_len, attr, name_len) = struct.unpack_from(" 0: hidden = (attr & 1) != 0 subdir = (attr & 2) != 0 if file_pos != dir_pos and file_pos != parent: name = dir[pos+33:pos+33+name_len] if not subdir: pat = re_name.match(name) if pat: name = pat.group(1) file_path = os.path.join(path, name) if subdir: list.extend( readDir(f, file_path, file_pos, file_len, dir_pos) ) else: list.append( (file_path, file_pos, file_len) ) pos += entry_size else: pos = (pos + 2047) & ~2047 del dir return list def readFileTable(f): fileTable = readSectorForm1( f, 24, 16 ) index = 0 fileCount = 0 dirCount = 0 dirIndex = 0 movies = False list = [] while True: startSector = struct.unpack_from(" 0: file_path = os.path.join("dir%i" % dirIndex, "file%i.bin" % fileCount) list.append( (file_path, startSector, fileSize, movies) ) fileCount += 1 index += 1 return list def main(*argv): for arg in argv: f = open(arg, "rb") # identify the disk volume_descriptor = readSectorForm1( f, 16, 1 ) (system_identifier, volume_identifier) = struct.unpack_from("<32s32s", volume_descriptor, 8) system_identifier = system_identifier.strip() if system_identifier != "PLAYSTATION": print "Not a playstation image: \"%s\"" % system_identifier f.close() return volume_identifier = volume_identifier.strip() if volume_identifier != "XENOGEARS": print "Not a Xenogears image: \"%s\"" % volume_identifier f.close() return # read the filesystem (root_pos,) = struct.unpack_from("