Пример #1
0
 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);
     }
 }
Пример #2
0
 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);
 }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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());
            }
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        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();
            }
        }