Exemple #1
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Big);

            input.Seek(-4, SeekOrigin.Current);

            if (magic == CDRMFile.Magic)
            {
                input = CDRMFile.Decompress(input);
            }

            var version = input.ReadValueU32();

            if (version != 14 && version.Swap() != 14 &&
                version != 19 && version.Swap() != 19 &&
                version != 21 && version.Swap() != 21)
            {
                throw new FormatException();
            }

            if (version == 14 || version == 19 || version == 21)
            {
                this.Endianness = Endian.Little;
            }
            else
            {
                this.Endianness = Endian.Big;
            }

            this.Version = this.Endianness == Endian.Little ? version : version.Swap();

            if (this.Version == 14)
            {
                throw new NotSupportedException("TRL/TRA not supported");
            }

            if (this.Version == 21)
            {
                throw new NotSupportedException("DX3 not supported");
            }

            if (input.Length < 24)
            {
                throw new FormatException("not enough data for header");
            }

            var unknown04_Size = input.ReadValueU32(this.Endianness);
            var unknown08_Size = input.ReadValueU32(this.Endianness);
            var unknown0C      = input.ReadValueU32(this.Endianness); // extra data after first block?
            var unknown10      = input.ReadValueU32(this.Endianness);
            var sectionCount   = input.ReadValueU32(this.Endianness);

            Debug.Assert((unknown0C + unknown10) == 0, "unk hdr val not 0");

            if (unknown0C != 0)
            {
                throw new FormatException(); //why?
            }

            var sectionHeaders = new DRM.SectionHeader[sectionCount];

            for (uint i = 0; i < sectionCount; i++)
            {
                sectionHeaders[i] = new DRM.SectionHeader();
                sectionHeaders[i].Deserialize(input, this.Endianness);
            }

            this.Unknown08s.Clear();
            using (var unknown08_Data = input.ReadToMemoryStream(unknown08_Size))
            {
                while (unknown08_Data.Position < unknown08_Data.Length)
                {
                    this.Unknown08s.Add(unknown08_Data.ReadStringZ(Encoding.ASCII));
                }
            }

            this.Unknown04s.Clear();
            using (var unknown04_Data = input.ReadToMemoryStream(unknown04_Size))
            {
                while (unknown04_Data.Position < unknown04_Data.Length)
                {
                    this.Unknown04s.Add(unknown04_Data.ReadStringZ(Encoding.ASCII));
                }
            }

            var sections = new DRM.Section[sectionCount];

            for (int i = 0; i < sectionCount; i++)
            {
                var sectionHeader = sectionHeaders[i];

                var section = new DRM.Section();
                section.Id        = sectionHeader.Id;
                section.Type      = sectionHeader.Type;
                section.Flags     = (byte)(sectionHeader.Flags & 0xFF);
                section.Unknown05 = sectionHeader.Unknown05;
                section.Unknown06 = sectionHeader.Unknown06;
                section.Unknown10 = sectionHeader.Unknown10;

                if ((sectionHeader.Unknown05 & 1) != 0)
                {
                    throw new NotImplementedException();
                }

                if (sectionHeader.HeaderSize > 0)
                {
                    using (var buffer = input.ReadToMemoryStream(sectionHeader.HeaderSize))
                    {
                        var resolver = new DRM.Resolver();
                        resolver.Deserialize(buffer, this.Endianness);
                        section.Resolver = resolver;
                    }
                }

                if (sectionHeader.DataSize > 0)
                {
                    section.Data = input.ReadToMemoryStream(sectionHeader.DataSize);
                }
                else
                {
                    section.Data = null;
                }

                sections[i] = section;
            }

            this.Sections.Clear();
            this.Sections.AddRange(sections);
        }
Exemple #2
0
        public Stream Serialize()
        {
            MemoryStream data         = new MemoryStream();
            uint         sectionCount = (uint)this.Sections.Count;

            Stream[] resolvers = new MemoryStream[sectionCount]; // for serialized resolvers

            uint unknown04_size = 0;
            uint unknown08_size = 0;

            // Write DRM Header
            data.WriteValueU32(this.Version, this.Endianness);
            data.WriteValueU32(0); // skip for now
            data.WriteValueU32(0); // skip for now
            data.WriteValueU32(0); // unknown0C
            data.WriteValueU32(0); // unknown10
            data.WriteValueU32(sectionCount, this.Endianness);

            // Write DRM Section Headers
            for (int i = 0; i < sectionCount; i++)
            {
                DRM.Section section = this.Sections[i];

                // Serialize resolvers to get length, data will be used later
                uint resolverLen;
                if (section.Resolver != null)
                {
                    resolvers[i] = section.Resolver.Serialize(this.Endianness);
                    resolverLen  = (uint)resolvers[i].Length;
                }
                else
                {
                    resolvers[i] = null;
                    resolverLen  = 0;
                }

                data.WriteValueU32((uint)section.Data.Length, this.Endianness);
                data.WriteValueU8((byte)section.Type);
                data.WriteValueU8(section.Unknown05);
                data.WriteValueU16(section.Unknown06, this.Endianness);
                data.WriteValueU32((uint)section.Flags | (resolverLen << 8), this.Endianness);
                data.WriteValueU32(section.Id, this.Endianness);
                data.WriteValueU32(section.Unknown10, this.Endianness);
            }

            // Write Unknown08s
            for (int i = 0; i < Unknown08s.Count; i++)
            {
                unknown08_size += ((uint)Unknown08s[i].Length + 1);
                data.WriteStringZ(Unknown08s[i]);
            }

            // Write Unknown04s
            for (int i = 0; i < Unknown04s.Count; i++)
            {
                unknown04_size += ((uint)Unknown04s[i].Length + 1);
                data.WriteStringZ(Unknown04s[i]);
            }

            // Write DRM Section Data
            for (int i = 0; i < sectionCount; i++)
            {
                if (resolvers[i] != null)
                {
                    data.WriteFromStream(resolvers[i], resolvers[i].Length);
                }
                data.WriteFromStream(this.Sections[i].Data, this.Sections[i].Data.Length);
                this.Sections[i].Data.Position = 0;
            }

            // Go back and write unknowns length
            data.Seek(4, SeekOrigin.Begin);
            data.WriteValueU32(unknown04_size);
            data.WriteValueU32(unknown08_size);

            data.Position = 0;
            return(data);
        }
Exemple #3
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Big);
            input.Seek(-4, SeekOrigin.Current);

            if (magic == CDRMFile.Magic)
            {
                input = CDRMFile.Decompress(input);
            }

            var version = input.ReadValueU32();
            if (version != 14 && version.Swap() != 14 &&
                version != 19 && version.Swap() != 19 &&
                version != 21 && version.Swap() != 21)
            {
                throw new FormatException();
            }

            if (version == 14 || version == 19 || version == 21)
                this.Endianness = Endian.Little;
            else
                this.Endianness = Endian.Big;

            this.Version = this.Endianness == Endian.Little ? version : version.Swap();

            if (this.Version == 14)
            {
                throw new NotSupportedException("TRL/TRA not supported");
            }

            if (this.Version == 21)
            {
                throw new NotSupportedException("DX3 not supported");
            }

            if (input.Length < 24)
            {
                throw new FormatException("not enough data for header");
            }

            var unknown04_Size = input.ReadValueU32(this.Endianness);
            var unknown08_Size = input.ReadValueU32(this.Endianness);
            var unknown0C = input.ReadValueU32(this.Endianness); // extra data after first block?
            var unknown10 = input.ReadValueU32(this.Endianness);
            var sectionCount = input.ReadValueU32(this.Endianness);

            Debug.Assert((unknown0C + unknown10) == 0, "unk hdr val not 0");

            if (unknown0C != 0)
            {
                throw new FormatException(); //why?
            }

            var sectionHeaders = new DRM.SectionHeader[sectionCount];
            for (uint i = 0; i < sectionCount; i++)
            {
                sectionHeaders[i] = new DRM.SectionHeader();
                sectionHeaders[i].Deserialize(input, this.Endianness);
            }

            this.Unknown08s.Clear();
            using (var unknown08_Data = input.ReadToMemoryStream(unknown08_Size))
            {
                while (unknown08_Data.Position < unknown08_Data.Length)
                {
                    this.Unknown08s.Add(unknown08_Data.ReadStringZ(Encoding.ASCII));
                }
            }

            this.Unknown04s.Clear();
            using (var unknown04_Data = input.ReadToMemoryStream(unknown04_Size))
            {
                while (unknown04_Data.Position < unknown04_Data.Length)
                {
                    this.Unknown04s.Add(unknown04_Data.ReadStringZ(Encoding.ASCII));
                }
            }

            var sections = new DRM.Section[sectionCount];
            for (int i = 0; i < sectionCount; i++)
            {
                var sectionHeader = sectionHeaders[i];

                var section = new DRM.Section();
                section.Id = sectionHeader.Id;
                section.Type = sectionHeader.Type;
                section.Flags = (byte)(sectionHeader.Flags & 0xFF);
                section.Unknown05 = sectionHeader.Unknown05;
                section.Unknown06 = sectionHeader.Unknown06;
                section.Unknown10 = sectionHeader.Unknown10;

                if ((sectionHeader.Unknown05 & 1) != 0)
                {
                    throw new NotImplementedException();
                }

                if (sectionHeader.HeaderSize > 0)
                {
                    using (var buffer = input.ReadToMemoryStream(sectionHeader.HeaderSize))
                    {
                        var resolver = new DRM.Resolver();
                        resolver.Deserialize(buffer, this.Endianness);
                        section.Resolver = resolver;
                    }
                }

                if (sectionHeader.DataSize > 0)
                {
                    section.Data = input.ReadToMemoryStream(sectionHeader.DataSize);
                }
                else
                {
                    section.Data = null;
                }

                sections[i] = section;
            }

            this.Sections.Clear();
            this.Sections.AddRange(sections);
        }