protected internal virtual void readToc() { toc = new Dictionary <int, int>(); nextFreeBufferedSectorNumber = 0; tocDirty = false; try { tocFile.seek(0); long Length = tocFile.Length(); if (Length >= 4) { numSectors = tocFile.readInt(); for (long i = 4; i < Length; i += 8) { int sectorNumber = tocFile.readInt(); int bufferedSectorNumber = tocFile.readInt(); toc[sectorNumber] = bufferedSectorNumber; nextFreeBufferedSectorNumber = System.Math.Max(nextFreeBufferedSectorNumber, bufferedSectorNumber + 1); } } else if (sectorDevice != null) { numSectors = sectorDevice.NumSectors; } } catch (IOException e) { Console.WriteLine("readToc", e); } }
public DataInputStream getChunkDataInputStream(int i, int j) { if (outOfBounds(i, j)) { debugln("READ", i, j, "out of bounds"); return(null); } try { int k = getOffset(i, j); if (k == 0) { return(null); } int l = k >> 8; int i1 = k & 0xff; if (l + i1 > sectorFree.size()) { debugln("READ", i, j, "invalid sector"); return(null); } dataFile.seek(l * 4096); int j1 = dataFile.readInt(); if (j1 > 4096 * i1) { debugln("READ", i, j, (new StringBuilder()).append("invalid length: ").append(j1).append(" > 4096 * ").append(i1). toString()); return(null); } byte byte0 = dataFile.readByte(); if (byte0 == 1) { var abyte0 = new byte[j1 - 1]; dataFile.read(abyte0); var datainputstream = new DataInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte0))); return(datainputstream); } if (byte0 == 2) { var abyte1 = new byte[j1 - 1]; dataFile.read(abyte1); var datainputstream1 = new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte1))); return(datainputstream1); } else { debugln("READ", i, j, (new StringBuilder()).append("unknown version ").append(byte0).toString()); return(null); } } catch (IOException) { debugln("READ", i, j, "exception"); } return(null); }
public virtual DataInputStream GetChunkDataInputStream(int x, int z) { if (OutOfBounds(x, z)) { return(null); } try { int offset = GetOffset(x, z); if (offset == 0) { return(null); } int sectorNumber = offset >> 8; int numSectors = offset & 0xFF; if (sectorNumber + numSectors > _sectorFree.Count) { return(null); } _file.seek(sectorNumber * SectorBytes); int length = _file.readInt(); if (length > SectorBytes * numSectors) { return(null); } byte version = _file.readByte(); if (version == VersionGzip) { byte[] data = new byte[length - 1]; _file.read(data); return(new DataInputStream(new ByteArrayInputStream(data))); } if (version != VersionDeflate) { return(null); } { byte[] data = new byte[length - 1]; _file.read(data); return(new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data)))); } } catch (Exception) { return(null); } }
public static void Main(string[] args) { try { RandomAccessFile inToc = new RandomAccessFile("tmp/umdbuffer.toc", "r"); RandomAccessFile inIso = new RandomAccessFile("tmp/umdbuffer.iso", "r"); RandomAccessFile outIso = new RandomAccessFile("tmp/umd.iso", "rw"); int numSectors = inToc.readInt(); Console.WriteLine(string.Format("numSectors={0:D}", numSectors)); sbyte[] buffer = new sbyte[sectorLength]; for (int i = 4; i < inToc.Length(); i += 8) { int sectorNumber = inToc.readInt(); int bufferedSectorNumber = inToc.readInt(); inIso.seek(bufferedSectorNumber * (long)sectorLength); inIso.readFully(buffer); outIso.seek(sectorNumber * (long)sectorLength); outIso.write(buffer); } inToc.close(); inIso.close(); outIso.close(); } catch (FileNotFoundException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } catch (IOException e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } }
public RegionFile(File path) { _offsets = new int[SectorInts]; _chunkTimeStamps = new int[SectorInts]; _fileName = path; _sizeDelta = 0; try { if (path.exists()) { LastModified = path.lastModified(); } _file = new RandomAccessFile(path, "rw"); if (_file.length() < SectorBytes) { // we need to write the chunk offset table for (int i = 0; i < SectorInts; ++i) { _file.writeInt(0); } // write another sector for the timestamp info for (int i = 0; i < SectorInts; ++i) { _file.writeInt(0); } _sizeDelta += SectorBytes * 2; } if ((_file.length() & 0xfff) != 0) { // the file size is not a multiple of 4KB, grow it for (int i = 0; i < (_file.length() & 0xfff); ++i) { _file.write(0); } } // set up the available sector map int nSectors = (int)_file.length() / SectorBytes; _sectorFree = new List <bool>(nSectors); for (int i = 0; i < nSectors; ++i) { _sectorFree.Add(true); } _sectorFree[0] = false; // chunk offset table _sectorFree[1] = false; // for the last modified info _file.seek(0); for (int i = 0; i < SectorInts; ++i) { int offset = _file.readInt(); _offsets[i] = offset; if (offset == 0 || (offset >> 8) + (offset & 0xFF) > _sectorFree.Count) { continue; } for (int sectorNum = 0; sectorNum < (offset & 0xFF); ++sectorNum) { _sectorFree[(offset >> 8) + sectorNum] = false; } } for (int i = 0; i < SectorInts; i++) { int lastModValue = _file.readInt(); _chunkTimeStamps[i] = lastModValue; } } catch (IOException e) { Console.WriteLine(e.ToString()); } }
public PBPFileSectorDevice(RandomAccessFile fileAccess) : base(fileAccess) { try { int magic = endianSwap32(fileAccess.readInt()); int version = endianSwap32(fileAccess.readInt()); offsetParamSFO = endianSwap32(fileAccess.readInt()); offsetIcon0 = endianSwap32(fileAccess.readInt()); offsetIcon1 = endianSwap32(fileAccess.readInt()); offsetPic0 = endianSwap32(fileAccess.readInt()); offsetPic1 = endianSwap32(fileAccess.readInt()); offsetSnd0 = endianSwap32(fileAccess.readInt()); offsetPspData = endianSwap32(fileAccess.readInt()); offsetPsarData = endianSwap32(fileAccess.readInt()); if (magic != 0x50425000) { throw new IOException(string.Format("Invalid PBP header 0x{0:X8}", magic)); } if (version != 0x00010000 && version != 0x00000100 && version != 0x00010001) { throw new IOException(string.Format("Invalid PBP version 0x{0:X8}", version)); } fileAccess.seek(offsetPsarData); sbyte[] header = new sbyte[256]; int readSize = fileAccess.read(header); if (readSize != header.Length) { int psarDataLength = (int)(fileAccess.Length() - offsetPsarData); if (psarDataLength != 0 && psarDataLength != 16) { throw new IOException(string.Format("Invalid PBP header")); } } else if (header[0] == (sbyte)'N' && header[1] == (sbyte)'P' && header[2] == (sbyte)'U' && header[3] == (sbyte)'M' && header[4] == (sbyte)'D' && header[5] == (sbyte)'I' && header[6] == (sbyte)'M' && header[7] == (sbyte)'G') { CryptoEngine cryptoEngine = new CryptoEngine(); amctrl = cryptoEngine.AMCTRLEngine; AMCTRL.BBMac_Ctx macContext = new AMCTRL.BBMac_Ctx(); AMCTRL.BBCipher_Ctx cipherContext = new AMCTRL.BBCipher_Ctx(); // getKey amctrl.hleDrmBBMacInit(macContext, 3); amctrl.hleDrmBBMacUpdate(macContext, header, 0xC0); sbyte[] macKeyC0 = new sbyte[16]; Array.Copy(header, 0xC0, macKeyC0, 0, macKeyC0.Length); vkey = amctrl.GetKeyFromBBMac(macContext, macKeyC0); // decrypt NP header sbyte[] cipherData = new sbyte[0x60]; Array.Copy(header, 0x40, cipherData, 0, cipherData.Length); Array.Copy(header, 0xA0, hkey, 0, hkey.Length); amctrl.hleDrmBBCipherInit(cipherContext, 1, 2, hkey, vkey); amctrl.hleDrmBBCipherUpdate(cipherContext, cipherData, cipherData.Length); amctrl.hleDrmBBCipherFinal(cipherContext); int lbaStart = Utilities.readUnaligned32(cipherData, 0x14); int lbaEnd = Utilities.readUnaligned32(cipherData, 0x24); numSectors = lbaEnd + 1; lbaSize = numSectors - lbaStart; blockLBAs = Utilities.readUnaligned32(header, 0x0C); blockSize = blockLBAs * ISectorDevice_Fields.sectorLength; numBlocks = (lbaSize + blockLBAs - 1) / blockLBAs; blockBuffer = new sbyte[blockSize]; tempBuffer = new sbyte[blockSize]; table = new TableInfo[numBlocks]; int tableOffset = Utilities.readUnaligned32(cipherData, 0x2C); fileAccess.seek(offsetPsarData + tableOffset); sbyte[] tableBytes = new sbyte[numBlocks * 32]; readSize = fileAccess.read(tableBytes); if (readSize != tableBytes.Length) { Console.WriteLine(string.Format("Could not read table with size {0:D} (readSize={1:D})", tableBytes.Length, readSize)); } IntBuffer tableInts = ByteBuffer.wrap(tableBytes).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); for (int i = 0; i < numBlocks; i++) { int p0 = tableInts.get(); int p1 = tableInts.get(); int p2 = tableInts.get(); int p3 = tableInts.get(); int p4 = tableInts.get(); int p5 = tableInts.get(); int p6 = tableInts.get(); int p7 = tableInts.get(); int k0 = p0 ^ p1; int k1 = p1 ^ p2; int k2 = p0 ^ p3; int k3 = p2 ^ p3; TableInfo tableInfo = new TableInfo(); Array.Copy(tableBytes, i * 32, tableInfo.mac, 0, tableInfo.mac.Length); tableInfo.offset = p4 ^ k3; tableInfo.size = p5 ^ k1; tableInfo.flags = p6 ^ k2; tableInfo.unknown = p7 ^ k0; table[i] = tableInfo; } currentBlock = -1; } } catch (IOException e) { Console.WriteLine("Reading PBP", e); } }
public RegionFile(File file) { lastModified = 0L; fileName = file; debugln((new StringBuilder()).append("REGION LOAD ").append(fileName).toString()); sizeDelta = 0; try { if (file.exists()) { lastModified = file.lastModified(); } dataFile = new RandomAccessFile(file, "rw"); if (dataFile.length() < 4096L) { for (int i = 0; i < 1024; i++) { dataFile.writeInt(0); } for (int j = 0; j < 1024; j++) { dataFile.writeInt(0); } sizeDelta += 8192; } if ((dataFile.length() & 4095L) != 0L) { for (int k = 0; k < (dataFile.length() & 4095L); k++) { dataFile.write(0); } } int l = (int)dataFile.length() / 4096; sectorFree = new ArrayList(l); for (int i1 = 0; i1 < l; i1++) { sectorFree.add(Boolean.valueOf(true)); } sectorFree.set(0, Boolean.valueOf(false)); sectorFree.set(1, Boolean.valueOf(false)); dataFile.seek(0L); for (int j1 = 0; j1 < 1024; j1++) { int l1 = dataFile.readInt(); offsets[j1] = l1; if (l1 == 0 || (l1 >> 8) + (l1 & 0xff) > sectorFree.size()) { continue; } for (int j2 = 0; j2 < (l1 & 0xff); j2++) { sectorFree.set((l1 >> 8) + j2, Boolean.valueOf(false)); } } for (int k1 = 0; k1 < 1024; k1++) { int i2 = dataFile.readInt(); chunkTimestamps[k1] = i2; } } catch (IOException ioexception) { ioexception.printStackTrace(); } }