private void Load(StructureValueCollection values, FileSegmenter segmenter) { _eofSegment = segmenter.WrapEOF((int) values.GetInteger("file size")); var metaOffset = (int) values.GetInteger("meta offset"); var metaSize = (int) values.GetInteger("meta size"); uint metaOffsetMask = values.GetInteger("meta offset mask"); var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x200, SegmentResizeOrigin.Beginning), segmenter); MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); IndexHeaderLocation = MetaArea.AddSegment(metaSegment); Type = (CacheFileType) values.GetInteger("type"); var headerGroup = new FileSegmentGroup(); headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None)); StringIDCount = (int) values.GetInteger("string table count"); var sidDataSize = (int) values.GetInteger("string table size"); StringIDData = segmenter.WrapSegment((int) values.GetInteger("string table offset"), sidDataSize, 1, SegmentResizeOrigin.End); StringIDIndexTable = segmenter.WrapSegment((int) values.GetInteger("string index table offset"), StringIDCount*4, 4, SegmentResizeOrigin.End); FileNameCount = (int) values.GetInteger("file table count"); var fileDataSize = (int) values.GetInteger("file table size"); FileNameData = segmenter.WrapSegment((int) values.GetInteger("file table offset"), fileDataSize, 1, SegmentResizeOrigin.End); FileNameIndexTable = segmenter.WrapSegment((int) values.GetInteger("file index table offset"), FileNameCount*4, 4, SegmentResizeOrigin.End); InternalName = values.GetString("internal name"); ScenarioName = values.GetString("scenario name"); StringArea = new FileSegmentGroup(); StringArea.AddSegment(segmenter.WrapSegment((int) values.GetInteger("string block offset"), StringIDCount*0x80, 0x80, SegmentResizeOrigin.End)); StringArea.AddSegment(StringIDIndexTable); StringArea.AddSegment(StringIDData); StringArea.AddSegment(FileNameIndexTable); StringArea.AddSegment(FileNameData); StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea); StringIDDataLocation = SegmentPointer.FromOffset(StringIDData.Offset, StringArea); FileNameIndexTableLocation = SegmentPointer.FromOffset(FileNameIndexTable.Offset, StringArea); FileNameDataLocation = SegmentPointer.FromOffset(FileNameData.Offset, StringArea); LocaleArea = new FileSegmentGroup(); var rawTableOffset = (int) values.GetInteger("raw table offset"); var rawTableSize = (int) values.GetInteger("raw table size"); RawTable = segmenter.WrapSegment(rawTableOffset, rawTableSize, 1, SegmentResizeOrigin.End); Checksum = values.GetInteger("checksum"); // Set up a bogus partition table Partitions = new Partition[1]; Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint) MetaArea.Size); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header _eofSegment = segmenter.WrapEOF((int) values.GetInteger("file size")); LoadInteropData(values); RawTable = CalculateRawTableSegment(segmenter); Type = (CacheFileType) values.GetInteger("type"); InternalName = values.GetString("internal name"); ScenarioName = values.GetString("scenario name"); XDKVersion = (int) values.GetInteger("xdk version"); FileSegment metaSegment = CalculateTagDataSegment(values, segmenter); if (metaSegment != null) { uint virtualBase = values.GetInteger("virtual base address"); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, virtualBase)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer(values.GetInteger("index header address"), MetaArea); Partitions = LoadPartitions(values.GetArray("partitions")); } else { Partitions = new Partition[0]; } CalculateStringGroup(values, segmenter); }
/* private void AdjustPartitions() { if (MetaArea == null) return; // Find the first partition with a non-null address and change it to the meta area's base address Partition partition = Partitions.First(p => p.BasePointer != null); if (partition != null) partition.BasePointer = SegmentPointer.FromPointer(MetaArea.BasePointer, MetaArea); // Recalculate the size of each partition int partitionEnd = MetaArea.Offset + MetaArea.Size; for (int i = Partitions.Length - 1; i >= 0; i--) { if (Partitions[i].BasePointer == null) continue; int offset = Partitions[i].BasePointer.AsOffset(); Partitions[i].Size = (uint) (partitionEnd - offset); partitionEnd = offset; } } */ /* private StructureValueCollection[] SerializePartitions() { if (Partitions == null) return new StructureValueCollection[0]; var results = new StructureValueCollection[Partitions.Length]; for (int i = 0; i < Partitions.Length; i++) { var values = new StructureValueCollection(); values.SetInteger("load address", Partitions[i].BasePointer != null ? Partitions[i].BasePointer.AsPointer() : 0); values.SetInteger("size", Partitions[i].Size); results[i] = values; } return results; } */ /// <summary> /// Rebuilds the interop data table in a cache file. /// </summary> /// <param name="localeArea">The localization area of the file.</param> /* private void RebuildInteropData(FileSegmentGroup localeArea) { FourthGenInteropSection debugSection = Sections[(int) FourthGenInteropSectionType.Debug]; FourthGenInteropSection rsrcSection = Sections[(int) FourthGenInteropSectionType.Resource]; FourthGenInteropSection tagSection = Sections[(int) FourthGenInteropSectionType.Tag]; FourthGenInteropSection localeSection = Sections[(int) FourthGenInteropSectionType.Localization]; // Recompute base addresses // Section addresses are usually in the following order: resource, locale, tag, debug. // Each address can immediately follow after the previous non-null section, // even though this isn't the case in some of the official files (because of removed debug data). // // TODO: This could possibly be made into a for loop and cleaned up if the pointer converters are stored in an array. // I just want to get this working for now. rsrcSection.VirtualAddress = 0; // This is always zero rsrcSection.Size = (ResourcePointerConverter != null) ? (uint) RawTable.Size : 0; localeSection.VirtualAddress = (LocalePointerConverter != null) ? rsrcSection.VirtualAddress + rsrcSection.Size : 0; localeSection.Size = (LocalePointerConverter != null) ? (uint) localeArea.Size : 0; tagSection.VirtualAddress = (TagBufferPointerConverter != null) ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size : 0; tagSection.Size = (TagBufferPointerConverter != null) ? (uint) MetaArea.Size : 0; debugSection.VirtualAddress = (DebugPointerConverter != null) ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size + tagSection.Size : 0; debugSection.Size = (DebugPointerConverter != null) ? (uint) StringArea.Size : 0; // If the offset mask for the debug section wasn't originally zero, then we have to subtract the first partition size from the debug base address // Not entirely sure why this is the case, but that's what the official files do if (debugSection.VirtualAddress != 0 && SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] != 0) debugSection.VirtualAddress -= Partitions[0].Size; // Recompute offset masks SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] = (debugSection.Size > 0) ? (uint) (StringArea.Offset - debugSection.VirtualAddress) : 0; SectionOffsetMasks[(int) FourthGenInteropSectionType.Resource] = (rsrcSection.Size > 0) ? (uint) (RawTable.Offset - rsrcSection.VirtualAddress) : 0; SectionOffsetMasks[(int) FourthGenInteropSectionType.Tag] = (tagSection.Size > 0) ? (uint) (MetaArea.Offset - tagSection.VirtualAddress) : 0; SectionOffsetMasks[(int) FourthGenInteropSectionType.Localization] = (localeSection.Size > 0) ? (uint) (localeArea.Offset - localeSection.VirtualAddress) : 0; // Update pointer converters if (DebugPointerConverter != null) DebugPointerConverter.BasePointer = debugSection.VirtualAddress; if (ResourcePointerConverter != null) ResourcePointerConverter.BasePointer = rsrcSection.VirtualAddress; if (TagBufferPointerConverter != null) TagBufferPointerConverter.BasePointer = tagSection.VirtualAddress; if (LocalePointerConverter != null) LocalePointerConverter.BasePointer = localeSection.VirtualAddress; } */ private void Load(StructureValueCollection map_values, StructureValueCollection tag_values, StructureValueCollection string_values, FileSegmenter map_segmenter) { map_segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header _eofSegment = map_segmenter.WrapEOF((int)map_values.GetInteger("file size")); //LoadInteropData(map_values, tag_values); //RawTable = CalculateRawTableSegment(segmenter); Type = (CacheFileType)map_values.GetInteger("type"); InternalName = map_values.GetString("internal name"); ScenarioPath = map_values.GetString("scenario path"); uint index_header_address = map_values.GetInteger("index header address"); // File Segment FileSegmenter tags_segmenter = new FileSegmenter(); tags_segmenter.DefineSegment(0, (int)EngineInfo.TagsDataSize, 0x1, SegmentResizeOrigin.Beginning); // Define a segment for the header FileSegment metaSegment = new FileSegment(0, tags_segmenter); //FileSegment metaSegment = CalculateTagDataSegment(tag_values, segmenter); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, index_header_address)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer(index_header_address, MetaArea); //XDKVersion = (int) values.GetInteger("xdk version"); /* FileSegment metaSegment = CalculateTagDataSegment(values, segmenter); if (metaSegment != null) { uint virtualBase = values.GetInteger("virtual base address"); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, virtualBase)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer(values.GetInteger("index header address"), MetaArea); Partitions = LoadPartitions(values.GetArray("partitions")); } else { Partitions = new Partition[0]; } */ CalculateStringGroup(string_values, map_segmenter); }