Exemplo n.º 1
0
        /// <summary>
        /// Stream the field from a buffer
        /// </summary>
        /// <param name="input"></param>
        public override void Read(IO.EndianReader input)
        {
            Internal = input.ReadBytes(Value);
#if DEBUG
            if (TracingEnabled && Value > 5)
            {
                byte[] data = input.ReadBytes(Value);
                for (int x = 0, y = 0, z = 0; x < data.Length; x++)
                {
                    if (data[x] != 0)
                    {
                        if (y == 0 || x == 0)
                        {
                            y = x;
                        }
                        z++;
                    }
                    else if (x != 0 && data[x - 1] != 0)
                    {
                        trace.WriteLine("Found data at offset 0x{0:X} covering 0x{1:X} bytes, in a pad field with a count of {1}", y, z, Value);
                    }
                }
                data = null;
            }
#endif
        }
Exemplo n.º 2
0
        /// <summary>Read a multi-byte CString from an endian stream</summary>
        /// <param name="s">Endian stream to read from</param>
        /// <param name="ms">Stream to write the character's bytes to</param>
        void ReadCStringMultiByte(IO.EndianReader s, System.IO.MemoryStream ms)
        {
            byte[] characters;
            if (!mStorage.IsFixedLength)
            {
                characters = new byte[mNullCharacterSize];
                while (!ReadStringMultiByteIsNull(s.ByteOrder, s.Read(characters), 0))
                {
                    ms.Write(characters, 0, characters.Length);
                }
            }
            else
            {
                characters = s.ReadBytes(mFixedLengthByteLength);

                int x;
                for (x = 0; x < characters.Length - mNullCharacterSize; x += mNullCharacterSize)
                {
                    if (ReadStringMultiByteIsNull(s.ByteOrder, characters, x))
                    {
                        break;
                    }
                }

                ms.Write(characters, 0, x);
            }
        }
Exemplo n.º 3
0
        public void Read(IO.EndianReader s)
        {
            s.Owner = this;

            Flags   = s.Read(FileFlagsStreamer.Instance);
            Version = s.ReadUInt16();
            if (Version != kVersion)
            {
                throw new IO.VersionMismatchException(s.BaseStream,
                                                      kVersion, Version);
            }

            Read(s, EnumFlags.Test(Flags, FileFlags.EncryptHeader), Header, MediaHeader.kSizeOf);
            GenerateHash();

            if (EnumFlags.Test(Flags, FileFlags.CompressContent))
            {
                using (var cs = new CompressedStream(true))
                {
                    Read(s, EnumFlags.Test(Flags, FileFlags.EncryptContent), cs,
                         userKey: Header.DataCryptKey, readLeftovers: ReadLeftovers);

                    cs.Decompress();
                    Content = cs.UncompressedData;
                }
            }
            else
            {
                Content = s.ReadBytes((int)(s.BaseStream.Length - s.BaseStream.Position));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Stream the field from a buffer
        /// </summary>
        /// <param name="input"></param>
        public override void Read(IO.EndianReader input)
        {
#if false//DEBUG
            if (Value < 5)
            {
                input.Seek(Value, System.IO.SeekOrigin.Current);
            }
            else
            {
                byte[] data = input.ReadBytes(Value);
                for (int x = 0, y = 0, z = 0; x < data.Length; x++)
                {
                    if (data[x] != 0)
                    {
                        if (y == 0 || x == 0)
                        {
                            y = x;
                        }
                        z++;
                    }
                    else if (x != 0 && data[x - 1] != 0)
                    {
                        trace.WriteLine("Found data at offset 0x{0:X} covering 0x{1:X} bytes, in a pad field with a count of {1}", y, z, Value);
                    }
                }
                data = null;
            }
#else
            input.Seek(Value, System.IO.SeekOrigin.Current);
#endif
        }
Exemplo n.º 5
0
        byte[] ReadStrCharArray(IO.EndianReader s, int length, out int actualCount)
        {
            byte[] bytes = s.ReadBytes(mStorage.IsFixedLength
                                ? mFixedLengthByteLength
                                : GetMaxCleanByteCount(length));

            actualCount = mNullCharacterSize == sizeof(byte)
                                ? ReadStrCharArrayGetRealCountSingleByte(bytes)
                                : ReadStrCharArrayGetRealCountMultiByte(s.ByteOrder, bytes);

            return(bytes);
        }
        int ReadChunk(IO.EndianReader s, System.IO.MemoryStream ms)
        {
            ushort chunk_size = s.ReadUInt16(), negate_chunk_size = s.ReadUInt16();

            ushort expected_negate = (ushort)~chunk_size;

            if (expected_negate != negate_chunk_size)
            {
                throw new IO.SignatureMismatchException(s.BaseStream,
                                                        expected_negate, negate_chunk_size);
            }

            byte[] bytes = s.ReadBytes(chunk_size);
            ms.Write(bytes, 0, bytes.Length);

            return(chunk_size);
        }
Exemplo n.º 7
0
        byte[] ReadStrPascal(IO.EndianReader s, out int actualCount)
        {
            actualCount = TypeExtensions.kNone;

            int length;

            // One would think that the length prefix would be of the same endian as the stream, but just in case...
            using (s.BeginEndianSwitch(mStorage.ByteOrder))
                switch (mStorage.LengthPrefix)
                {
                case StringStorageLengthPrefix.Int7: length = s.Read7BitEncodedInt(); break;

                case StringStorageLengthPrefix.Int8: length = s.ReadByte(); break;

                case StringStorageLengthPrefix.Int16: length = s.ReadInt16(); break;

                case StringStorageLengthPrefix.Int32: length = s.ReadInt32(); break;

                default: throw new Debug.UnreachableException();
                }

            return(s.ReadBytes(GetMaxCleanByteCount(length)));
        }
Exemplo n.º 8
0
        /// <summary>Read a CString from an endian stream</summary>
        /// <param name="s">Endian stream to read from</param>
        /// <param name="length">Optional length specification</param>
        /// <param name="actualCount">On return, the actual character byte count, or -1 if all bytes are valid</param>
        /// <returns>The character's bytes for the string we're reading</returns>
        byte[] ReadStrCString(IO.EndianReader s, int length, out int actualCount)
        {
            byte[] bytes;

            actualCount = TypeExtensions.kNone;             // complete string case

            // the user was nice and saved us some CPU trying to feel around for the null
            // because we don't have a fixed length to speed things up
            if (!mStorage.IsFixedLength && length > 0)
            {
                bytes = s.ReadBytes(GetMaxCleanByteCount(length));
                s.Seek(mNullCharacterSize, System.IO.SeekOrigin.Current);
            }
            // F**K: figure out the length ourselves. Or maybe we're a fixed length CString...
            // in which case we'll ignore anything the user tried to tell us about the length
            else
            {
                using (var ms = new System.IO.MemoryStream(!mStorage.IsFixedLength ? 512 : mStorage.FixedLength))
                {
                    // The N-byte methods take care of reading past the
                    // null character, no need to do it in this case.
                    if (mNullCharacterSize == 1)
                    {
                        ReadCStringSingleByte(s, ms);
                    }
                    else
                    {
                        ReadCStringMultiByte(s, ms);
                    }

                    // We use ToArray instead of GetArray so all of [ms] can theoretically be disposed of
                    bytes = ms.ToArray();
                }
            }

            return(bytes);
        }
Exemplo n.º 9
0
            bool CacheRead(BlamLib.Blam.CacheFile c, out byte[] data)
            {
                data = null;

                ResourcePtr offset = GetOffset(0);
                int         size   = GetSize(0);

                var rsrc_cache = Program.Halo2.FromLocation(c as Halo2.CacheFile, offset);

                // the shared cache isn't loaded, break
                if (rsrc_cache == null)
                {
                    return(false);
                }

                // get the input stream we need
                IO.EndianReader er = rsrc_cache.InputStream;

                // read the bitmap
                er.Seek(offset.Offset);
                data = er.ReadBytes(size);

                return(true);
            }
        public override void Read(IO.EndianReader s)
        {
            int k_local_sizeof = Blam.CacheFile.ValidateHeader(s, kSizeOf);

            s.Seek(4);
            version = s.ReadInt32();
            if (version != 11 && version != 12)
            {
                throw new InvalidCacheFileException(s.FileName);
            }
            fileLength = s.ReadInt32();
            s.ReadInt32();
            tagIndexAddress    = s.ReadUInt32();
            memoryBufferOffset = s.ReadInt32();
            memoryBufferSize   = s.ReadInt32();

            sourceFile = s.ReadAsciiString(256);
            build      = s.ReadTagString();
            cacheType  = (Blam.CacheType)s.ReadInt16();
            sharedType = (Cache.SharedType)s.ReadInt16();

            s.ReadBool();
            s.ReadBool();             // false if it belongs to a untracked build
            s.ReadBool();
            // PATCH: this is '3' in main menu patches
            s.ReadByte();             // appears to be an ODST-only field

            s.ReadInt32(); s.ReadInt32();
            s.ReadInt32(); s.ReadInt32(); s.ReadInt32();

            #region string id table
            // 0x158
            stringIdsCount        = s.ReadInt32();
            stringIdsBufferSize   = s.ReadInt32();
            stringIdIndicesOffset = s.ReadInt32();
            stringIdsBufferOffset = s.ReadInt32();
            #endregion

            #region filetimes?
            // pretty sure this is a flags field
            // used to tell which of the following 64bit values
            // are used. Damn sure this are FILETIME structures, but
            // hex workshop doesn't like them so I can't be for sure...
            needsShared             = s.ReadInt32() != 0; // just a little 'hack' if you will. if zero, the map is self reliant, so no worries
            Filetime.dwHighDateTime = s.ReadInt32();
            Filetime.dwLowDateTime  = s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnMainMenu);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnShared);
            }
            s.ReadInt32();
            if (s.ReadInt32() != 0)
            {
                flags.Add(Halo3.CacheHeaderFlags.DependsOnCampaign);
            }
            s.ReadInt32();
            #endregion

            name = s.ReadTagString();
            s.ReadInt32();
            scenarioPath = s.ReadAsciiString(256);
            // PATCH: this is -1 in main menu patches
            s.ReadInt32();             // minor version, normally not used

            #region tag paths
            tagNamesCount        = s.ReadInt32();
            tagNamesBufferOffset = s.ReadInt32();           // cstring buffer
            tagNamesBufferSize   = s.ReadInt32();           // cstring buffer total size in bytes
            tagNameIndicesOffset = s.ReadInt32();

            TagsUnknown1Count  = s.ReadInt32();
            TagsUnknown1Offset = s.ReadInt32();
            // PATCH: zero for non-patch data
            TagsUnknown2Count  = s.ReadInt32();
            TagsUnknown2Offset = s.ReadInt32();
            #endregion

            checksum = s.ReadUInt32();                // 0x2D4
            s.Seek(32, System.IO.SeekOrigin.Current); // these bytes are always the same. first 8 changed in Halo4

            baseAddress = s.ReadUInt32();             // expected base address
            xdkVersion  = s.ReadInt32();              // xdk version

            #region memory partitions
            // 0x300

            // memory partitions
            memoryPartitions = new Partition[6];
            memoryPartitions[0].BaseAddress = s.ReadUInt32();             // cache resource buffer
            memoryPartitions[0].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[1].BaseAddress = s.ReadUInt32();             // cache gestalt resource buffer
            memoryPartitions[1].Size        = s.ReadInt32();

            memoryPartitions[2].BaseAddress = s.ReadUInt32();             // global tags buffer (cache sound tags likes this memory space too)
            memoryPartitions[2].Size        = s.ReadInt32();
            memoryPartitions[3].BaseAddress = s.ReadUInt32();             // shared tag blocks? (havok data likes this memory space too)
            memoryPartitions[3].Size        = s.ReadInt32();
            memoryPartitions[4].BaseAddress = s.ReadUInt32();             // address
            memoryPartitions[4].Size        = s.ReadInt32();

            // readonly
            memoryPartitions[5].BaseAddress = s.ReadUInt32();             // map tags buffer
            memoryPartitions[5].Size        = s.ReadInt32();
            #endregion

            int count = s.ReadInt32();
            s.Seek(4 + 8, System.IO.SeekOrigin.Current);             // these bytes are always the same
            // if there is a hash in the header, this is the ONLY
            // place where it can be
            s.Seek(20 /*SHA1*/ + 40 + 256 /*RSA*/, System.IO.SeekOrigin.Current);             // ???

            // 0x47C
            cacheInterop.Read(s);
            cacheInterop.PostprocessForCacheRead(k_local_sizeof);

            s.Seek(16, System.IO.SeekOrigin.Current);             // GUID?, these bytes are always the same. ODST is different from Halo 3

            // PATCH: main menu patches have a single entry (where stock has none)
            #region blah 1
            // 0x4AC

            // campaign has a shit load of these
            // but shared doesn't nor mainmenu
            // I compared the sc110 french and english and both have the SAME counts and element data. So
            // I don't think this is a hash or something. At least, if it is, it's not runtime relative so
            // nothing we have to worry about

            s.ReadInt16();             // I've only seen this be two different values (besides zero).
            count = s.ReadInt16();     // I think the above specifies the size of the structure this count represents?
            s.ReadInt32();             // seems to always be zero
            CompressionGuid = new Guid(s.ReadBytes(16));

            s.Seek(count * 28, System.IO.SeekOrigin.Current);             // seek past the elements
            // dword
            // long
            // buffer [0x14] (probably a sha1 hash)
            s.Seek((3600 - count) * 28, System.IO.SeekOrigin.Current);             // seek past the unused elements
            #endregion

            // PATCH: main menu patches have a count of '1' but doesn't appear to have
            #region blah 2
            s.Seek(sizeof(uint) + 0x4E9C, System.IO.SeekOrigin.Current);
#if false
            {
                // 0x18E94

                // going to punt and just assume there is a max count of 13 of these possible

                // maybe related to bsp\'zones'?
                const int blah2_sizeof = 0x60C;

                count = (int)(s.ReadUInt32() >> 24);                               // did someone forget to f*****g byte swap something?
                s.Seek(count * blah2_sizeof, System.IO.SeekOrigin.Current);        // seek past the elements
                s.Seek((13 - count) * blah2_sizeof, System.IO.SeekOrigin.Current); // seek past the unused elements
            }
#endif
            #endregion

            s.Seek(712 + sizeof(uint), System.IO.SeekOrigin.Current);


            ReadPostprocessForInterop();

            if (!cacheInterop.IsNull)
            {
                int debug_mask = (int)cacheInterop[CacheSectionType.Debug].AddressMask;
                if (TagsUnknown1Offset != 0)
                {
                    TagsUnknown1Offset -= debug_mask;
                }
                if (TagsUnknown2Offset != 0)
                {
                    TagsUnknown2Offset -= debug_mask;
                }
            }

            ReadPostprocessForBaseAddresses(s);
        }
Exemplo n.º 11
0
            void ReadInt(IO.EndianReader s)
            {
                switch (TypeDesc.SizeOf)
                {
                case sizeof(byte):
                {
                    if (ArrayLength == 1)
                    {
                        Int = TypeDesc.IsUnsigned
                                                                ? (uint)s.ReadByte()
                                                                : (uint)s.ReadSByte();
                    }
                    else
                    {
                        if (TypeDesc.IsUnsigned)
                        {
                            var array = s.ReadBytes(ArrayLength);

                            OpaqueArrayRef = array;
                        }
                        else
                        {
                            var array = new sbyte[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadSByte();
                            }

                            OpaqueArrayRef = array;
                        }
                    }
                } break;

                case sizeof(ushort):
                {
                    if (ArrayLength == 1)
                    {
                        Int = TypeDesc.IsUnsigned
                                                                ? (uint)s.ReadUInt16()
                                                                : (uint)s.ReadInt16();
                    }
                    else
                    {
                        if (TypeDesc.IsUnsigned)
                        {
                            var array = new ushort[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadUInt16();
                            }

                            OpaqueArrayRef = array;
                        }
                        else
                        {
                            var array = new short[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadInt16();
                            }

                            OpaqueArrayRef = array;
                        }
                    }
                } break;

                case sizeof(uint):
                {
                    if (ArrayLength == 1)
                    {
                        Int = TypeDesc.IsUnsigned
                                                                ? (uint)s.ReadUInt32()
                                                                : (uint)s.ReadInt32();
                    }
                    else
                    {
                        if (TypeDesc.IsUnsigned)
                        {
                            var array = new uint[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadUInt32();
                            }

                            OpaqueArrayRef = array;
                        }
                        else
                        {
                            var array = new int[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadInt32();
                            }

                            OpaqueArrayRef = array;
                        }
                    }
                } break;

                case sizeof(ulong):
                {
                    if (ArrayLength == 1)
                    {
                        Int64 = TypeDesc.IsUnsigned
                                                                ? (ulong)s.ReadUInt64()
                                                                : (ulong)s.ReadInt64();
                    }
                    else
                    {
                        if (TypeDesc.IsUnsigned)
                        {
                            var array = new ulong[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadUInt64();
                            }

                            OpaqueArrayRef = array;
                        }
                        else
                        {
                            var array = new long[ArrayLength];
                            for (int x = 0; x < array.Length; x++)
                            {
                                array[x] = s.ReadInt64();
                            }

                            OpaqueArrayRef = array;
                        }
                    }
                } break;

                default:
                    throw new KSoft.Debug.UnreachableException(TypeDesc.SizeOf.ToString());
                }
            }
        public void ExtractSounds(string path, System.IO.StreamWriter towav, IO.EndianReader pckReader,
                                  bool overwriteExisting = false)
        {
            Dictionary <uint, SoundBank.AkSoundBankHierarchyObjectBase> sounds;

            if (!mObjects.TryGetValue(SoundBank.HircType.Sound, out sounds))
            {
                Debug.Trace.FilePackage.TraceInformation("{0} - No sounds to extract?",
                                                         PackageFileName);
                return;
            }

            foreach (var kv in sounds)
            {
                var snd = kv.Value as SoundBank.AkSoundBankHierarchySound;
                if (snd.Name == null && mDupObjects.Contains(kv.Key))
                {
                    continue;
                }

                uint src_id = snd.Source.MediaInfo.SourceID;
                mUntouched.Remove(src_id);

                if (snd.Source.MediaInfo.FileID == 0)
                {
                    towav.WriteLine("REM NoData {0}", snd.Name);
                    continue;
                }

                string dir      = null;
                string filename = (snd.Name ?? ("unknown_" + kv.Key.ToString("X8"))) + ".xma";

                uint   bank_id = snd.BankId;
                string bank_name;
                if (!Package.IdToName.TryGetValue(bank_id, out bank_name))
                {
                    bank_name = bank_id.ToString("X8");
                }

                SoundBank.AkSoundBankData bank_data = null;
                bool streamed = snd.Source.StreamType != SoundBank.AkBankSourceData.SourceType.Data;
                if (!streamed)
                {
                    bank_data = mIdToBank[bank_id].mData;
                }

                dir = System.IO.Path.Combine(path, bank_name);
                System.IO.Directory.CreateDirectory(dir);

                string full_path = System.IO.Path.Combine(dir, filename);
                towav.WriteLine("towav.exe {0}", full_path);

                if (System.IO.File.Exists(full_path) && !overwriteExisting)
                {
                    continue;
                }

                using (var fs = System.IO.File.Create(full_path))
                {
                    if (streamed)
                    {
                        var file = Package.FindStreamedFileById(snd.Source.MediaInfo.FileID);
                        pckReader.Seek(file.FileOffset);
                        byte[] data = pckReader.ReadBytes((int)file.FileSize32);

                        fs.Write(data, 0, data.Length);
                    }
                    else
                    {
                        fs.Write(bank_data.Buffer, (int)snd.Source.MediaInfo.FileOffset, (int)snd.Source.MediaInfo.MediaSize);
                    }
                }
            }
            //////////////////////////////////////////////////////////////////////////
            foreach (var kv in mUntouched)
            {
                var mr = kv.Value;

                string name = "unknown2_" + mr.Media.ID.ToString("X8");
                if (mr.Media.Size == 0)
                {
                    towav.WriteLine("REM NoData2 {0}", name);
                    continue;
                }

                string filename = name + ".xma";

                uint   bank_id = mr.BankId;
                string bank_name;
                if (!Package.IdToName.TryGetValue(bank_id, out bank_name))
                {
                    bank_name = bank_id.ToString("X8");
                }

                SoundBank.AkSoundBankData bank_data = mIdToBank[bank_id].mData;

                string dir = System.IO.Path.Combine(path, bank_name);
                System.IO.Directory.CreateDirectory(dir);

                string full_path = System.IO.Path.Combine(dir, filename);
                towav.WriteLine("towav.exe {0}", full_path);

                if (System.IO.File.Exists(full_path))
                {
                    continue;
                }

                using (var fs = System.IO.File.Create(full_path))
                {
                    fs.Write(bank_data.Buffer, (int)mr.Media.Offset, (int)mr.Media.Size);
                }
            }
        }
Exemplo n.º 13
0
        public void Read(IO.EndianReader s)
        {
            var context = s.UserData as XmbFileContext;

            using (s.ReadSignatureWithByteSwapSupport(kSignature))
            {
                if (context.PointerSize == Shell.ProcessorSize.x64)
                {
                    // #HACK to deal with xmb files which weren't updated with new tools
                    if (s.ByteOrder == Shell.EndianFormat.Big)
                    {
                        context.PointerSize = Shell.ProcessorSize.x32;
                    }
                }

                s.VirtualAddressTranslationInitialize(context.PointerSize);

                Values.PtrHandle elements_offset_pos;

                if (context.PointerSize == Shell.ProcessorSize.x64)
                {
                    s.Pad32();
                }
                #region Initialize elements
                {
                    int count = s.ReadInt32();
                    if (context.PointerSize == Shell.ProcessorSize.x64)
                    {
                        s.Pad32();
                    }
                    s.ReadVirtualAddress(out elements_offset_pos);

                    mElements = new List <Element>(count);
                }
                #endregion
                #region Initialize and read pool
                {
                    int size = s.ReadInt32();
                    if (context.PointerSize == Shell.ProcessorSize.x64)
                    {
                        s.Pad32();
                    }
                    Values.PtrHandle pool_offset_pos = s.ReadVirtualAddress();

                    s.Seek((long)pool_offset_pos);
                    byte[] buffer = s.ReadBytes(size);

                    mPool = new XmbVariantMemoryPool(buffer, s.ByteOrder);
                }
                #endregion

                if (context.PointerSize == Shell.ProcessorSize.x64)
                {
                    s.Pad64();
                }

                s.Seek((long)elements_offset_pos);
                for (int x = 0; x < mElements.Capacity; x++)
                {
                    var e = new Element();
                    mElements.Add(e);

                    e.Index = x;
                    e.Read(this, context, s);
                }

                foreach (var e in mElements)
                {
                    e.ReadAttributes(this, s);
                    e.ReadChildren(s);
                }
            }
        }