Пример #1
0
 /// <summary>
 /// Studies and patches a file.
 /// </summary>
 /// <param name="patch">The patch file to study.</param>
 /// <param name="study">The study struct to use for patching.</param>
 /// <param name="source">The unpatched source file.</param>
 /// <param name="target">The target file to copy the source file to, but with the patch applied.</param>
 public void PatchStudy(string patch, Studier.IpsStudy study, string source, string target)
 {
     using (FileStream patchStream = File.OpenRead(patch), sourceStream = File.OpenRead(source), targetStream = File.Open(target, FileMode.Create))
     {
         PatchStudy(patchStream, study, sourceStream, targetStream);
     }
 }
Пример #2
0
        /// <summary>
        /// Patches a stream.
        /// </summary>
        /// <param name="patch">The patch stream.</param>
        /// <param name="source">The unpatched source stream.</param>
        /// <param name="target">The target stream to write the source stream to, but with the patch applied.</param>
        public void Patch(Stream patch, Stream source, Stream target)
        {
            Studier studier = new Studier();

            Studier.IpsStudy study = studier.Study(patch);
            PatchStudy(patch, study, source, target);
        }
Пример #3
0
        /// <summary>
        /// Studies and patches a stream.
        /// </summary>
        /// <param name="patch">The patch stream to study.</param>
        /// <param name="study">The study struct to use for patching.</param>
        /// <param name="source">The unpatched source stream.</param>
        /// <param name="target">The target stream to copy the source stream to, but with the patch applied.</param>
        public void PatchStudy(Stream patch, Studier.IpsStudy study, Stream source, Stream target)
        {
            source.CopyTo(target);
            long sourceLength = source.Length;

            if (study.Error == Studier.IpsError.IpsInvalid)
            {
                throw new Exceptions.IpsInvalidException();
            }
            int outlen = (int)Clamp(target.Length, study.OutlenMin, study.OutlenMax);

            // Set target file length to new size.
            target.SetLength(outlen);

            // Skip PATCH text.
            patch.Seek(5, SeekOrigin.Begin);
            int offset = Reader.Read24(patch);

            while (offset != EndOfFile)
            {
                int size = Reader.Read16(patch);


                target.Seek(offset, SeekOrigin.Begin);
                // If RLE patch.
                if (size == 0)
                {
                    int  runLength = Reader.Read16(patch);
                    byte value     = Reader.Read8(patch);
                    target.Write(Enumerable.Repeat(value, runLength).ToArray(), 0, runLength);
                }
                // If normal patch.
                else
                {
                    byte[] data = new byte[size];
                    patch.Read(data, 0, size);
                    target.Write(data, 0, size);
                }
                offset = Reader.Read24(patch);
            }
            if (study.OutlenMax != 0xFFFFFFFF && sourceLength <= study.OutlenMax)
            {
                throw new Exceptions.IpsNotThisException();                                                                   // Truncate data without this being needed is a poor idea.
            }
        }