Example #1
0
        /// <summary>
        /// Returns this instance of PK2Entry as byte[] which can be used to be written back to the PK2 archive
        /// </summary>
        /// <returns></returns>
        public byte[] ToByteArray()
        {
            var result = new byte[128];

            using (var stream = new StreamWorker(result, StreamOperation.Write))
            {
                stream.WriteByte(Type);
                stream.WriteString(Name);
                stream.WriteByteArray(new byte[81 - Name.Length]); //Write the name padding
                stream.WriteLong(AccessTime.Ticks);
                stream.WriteLong(CreateTime.Ticks);
                stream.WriteLong(ModifyTime.Ticks);
                stream.WriteULong(Position);
                stream.WriteUInt(Size);
                stream.WriteULong(NextChain);
                stream.WriteByteArray(new byte[2]); //Padding to reach 128 bytes length
            }

            //If we have an encypted archive we have to encrypt this, too
            if (BlowfishUtilities.GetBlowfish() != null)
            {
                result = BlowfishUtilities.GetBlowfish().Encode(result);
            }

            return(result);
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PK2Block" /> class.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="offset">The block offset.</param>
        public PK2Block(byte[] buffer, ulong offset)
        {
            Entries = new PK2Entry[20];
            Offset  = offset;

            using (var streamWorker = new StreamWorker(buffer, StreamOperation.Read))
            {
                for (var i = 0; i < 20; i++)
                {
                    var entryBuffer = streamWorker.ReadByteArray(128);

                    if (BlowfishUtilities.GetBlowfish() != null)
                    {
                        entryBuffer = BlowfishUtilities.GetBlowfish().Decode(entryBuffer);
                    }

                    Entries[i] = new PK2Entry(entryBuffer, this, (byte)i);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">PK2Archive</exception>
        public void Dispose()
        {
            if (IsDisposed || IsDisposing)
            {
                throw new ObjectDisposedException("PK2Archive");
            }

            IsDisposing = true;

            BlowfishUtilities.SetBlowfish(null);
            IO.FileAdapter.SetInstance(null);
            Header       = null;
            Config       = null;
            Blocks       = null;
            Loaded       = false;
            _directories = null;
            _files       = null;
            _navigator   = null;

            IsDisposing = false;
            IsDisposed  = true;
        }
Example #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PK2Archive"/> class.
        /// The key is set to the isro standard encryption key.
        /// Do not provide any baseKey, if you wish to use the default base key for the archive.
        /// </summary>
        /// <exception cref="System.IO.FileNotFoundException"></exception>
        /// <exception cref="SlimPK2.Security.BlowfishSecurityException"></exception>
        /// <exception cref="SlimPK2.Types.InvalidHeaderException"></exception>
        public PK2Archive(string path, PK2Config config = null)
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException(path);
            }

            //Initialize default config
            if (config == null)
            {
                config = PK2Config.GetDefault();
            }

            //assign the config to this instance
            Config = config;

            //Create file reader...
            FileAdapter.SetInstance(new FileAdapter(path));
            Path = path;

            //Read header...
            Header = new PK2Header(FileAdapter.GetInstance().ReadData(0, 256));

            if (Header.Encrypted)
            {
                var blowfishKey = BlowfishUtilities.GenerateFinalBlowfishKey(Config.Key, Config.BaseKey);
                var blowfish    = new Blowfish();
                blowfish.Initialize(blowfishKey);
                BlowfishUtilities.SetBlowfish(blowfish);

                var tempChecksum =
                    BlowfishUtilities.GetBlowfish().Encode(Encoding.ASCII.GetBytes("Joymax Pak File"));

                //Check if the security checksum equals the generated checksum
                if (tempChecksum[0] != Header.SecurityChecksum[0] ||
                    tempChecksum[1] != Header.SecurityChecksum[1] ||
                    tempChecksum[2] != Header.SecurityChecksum[2])
                {
                    throw new BlowfishSecurityException(Config.Key);
                }
            }

            if (Config.Mode != PK2Mode.FreeBrowse)
            {
                switch (Config.Mode)
                {
                case PK2Mode.IndexBlocks:
                    Blocks = new List <PK2Block>();
                    ReadBlockAt(256);
                    break;

                case PK2Mode.Index:
                    _files       = new List <PK2File>();
                    _directories = new List <PK2Directory>();

                    ReadBlockAt(256, new PK2Directory());
                    break;
                }
            }
            else
            {
                _navigator = new PK2Navigator();
            }

            Loaded = true;
        }