private static ExtractedResourceInfo ReadResource(IReader reader, byte version) { if (version != 1) { throw new InvalidOperationException("Unrecognized \"rsrc\" block version"); } var originalIndex = new DatumIndex(reader.ReadUInt32()); var resource = new ExtractedResourceInfo(originalIndex); resource.Flags = reader.ReadUInt32(); resource.Type = reader.ReadAscii(); if (string.IsNullOrEmpty(resource.Type)) { resource.Type = null; } resource.Info = ReadByteArray(reader); resource.OriginalParentTagIndex = new DatumIndex(reader.ReadUInt32()); byte hasLocation = reader.ReadByte(); if (hasLocation != 0) { resource.Location = new ExtractedResourcePointer(); resource.Location.OriginalPrimaryPageIndex = reader.ReadInt32(); resource.Location.PrimaryOffset = reader.ReadInt32(); resource.Location.PrimaryUnknown = reader.ReadInt32(); resource.Location.OriginalSecondaryPageIndex = reader.ReadInt32(); resource.Location.SecondaryOffset = reader.ReadInt32(); resource.Location.SecondaryUnknown = reader.ReadInt32(); } resource.Unknown1 = reader.ReadInt32(); resource.Unknown2 = reader.ReadInt32(); resource.Unknown3 = reader.ReadInt32(); int numResourceFixups = reader.ReadInt32(); for (int i = 0; i < numResourceFixups; i++) { var fixup = new ResourceFixup(); fixup.Offset = reader.ReadInt32(); fixup.Address = reader.ReadUInt32(); resource.ResourceFixups.Add(fixup); } int numDefinitionFixups = reader.ReadInt32(); for (int i = 0; i < numDefinitionFixups; i++) { var fixup = new ResourceDefinitionFixup(); fixup.Offset = reader.ReadInt32(); fixup.Type = reader.ReadInt32(); resource.DefinitionFixups.Add(fixup); } return(resource); }
public DatumIndex InjectResource(ExtractedResourceInfo resource, IStream stream) { if (_resources == null) return DatumIndex.Null; if (resource == null) throw new ArgumentNullException("resource is null"); // Don't inject the resource if it's already been injected DatumIndex newIndex; if (_resourceIndices.TryGetValue(resource, out newIndex)) return newIndex; // Create a new datum index for it (0x4152 = 'AR') and associate it LoadResourceTable(stream); newIndex = new DatumIndex(0x4152, (ushort) _resources.Resources.Count); _resourceIndices[resource] = newIndex; // Create a native resource for it var newResource = new Resource(); _resources.Resources.Add(newResource); newResource.Index = newIndex; newResource.Flags = resource.Flags; newResource.Type = resource.Type; newResource.Info = resource.Info; if (resource.OriginalParentTagIndex.IsValid) { DatumIndex parentTagIndex = InjectTag(resource.OriginalParentTagIndex, stream); newResource.ParentTag = _cacheFile.Tags[parentTagIndex]; } if (resource.Location != null) { newResource.Location = new ResourcePointer(); // Primary page pointers if (resource.Location.OriginalPrimaryPageIndex >= 0) { int primaryPageIndex = InjectResourcePage(resource.Location.OriginalPrimaryPageIndex, stream); newResource.Location.PrimaryPage = _resources.Pages[primaryPageIndex]; } newResource.Location.PrimaryOffset = resource.Location.PrimaryOffset; newResource.Location.PrimaryUnknown = resource.Location.PrimaryUnknown; // Secondary page pointers if (resource.Location.OriginalSecondaryPageIndex >= 0) { int secondaryPageIndex = InjectResourcePage(resource.Location.OriginalSecondaryPageIndex, stream); newResource.Location.SecondaryPage = _resources.Pages[secondaryPageIndex]; } newResource.Location.SecondaryOffset = resource.Location.SecondaryOffset; newResource.Location.SecondaryUnknown = resource.Location.SecondaryUnknown; } newResource.ResourceFixups.AddRange(resource.ResourceFixups); newResource.DefinitionFixups.AddRange(resource.DefinitionFixups); newResource.Unknown1 = resource.Unknown1; newResource.Unknown2 = resource.Unknown2; newResource.Unknown3 = resource.Unknown3; // Make it load LoadZoneSets(stream); if (_zoneSets != null && _zoneSets.GlobalZoneSet != null) _zoneSets.GlobalZoneSet.ActivateResource(newResource, true); return newIndex; }
public DatumIndex InjectResource(ExtractedResourceInfo resource, IStream stream) { if (_resources == null) { return(DatumIndex.Null); } if (resource == null) { throw new ArgumentNullException("resource is null"); } // Don't inject the resource if it's already been injected DatumIndex newIndex; if (_resourceIndices.TryGetValue(resource, out newIndex)) { return(newIndex); } // Create a new datum index for it and associate it LoadResourceTable(stream); if (resource.OriginalParentTagIndex.Index == DatumIndex.Null.Index) { newIndex = new DatumIndex((ushort)0xFFFF, (ushort)_resources.Resources.Count); } else { newIndex = new DatumIndex((ushort)(0x8152 + _resourceIndices.Count), (ushort)_resources.Resources.Count); } _resourceIndices[resource] = newIndex; // Create a native resource for it var newResource = new Resource(); _resources.Resources.Add(newResource); newResource.Index = newIndex; newResource.Flags = resource.Flags; newResource.Type = resource.Type; newResource.Info = resource.Info; if (resource.OriginalParentTagIndex.IsValid) { DatumIndex parentTagIndex = InjectTag(resource.OriginalParentTagIndex, stream); newResource.ParentTag = _cacheFile.Tags[parentTagIndex]; } if (resource.Location != null) { newResource.Location = new ResourcePointer(); // Primary page pointers if (resource.Location.OriginalPrimaryPageIndex >= 0) { int primaryPageIndex = -1; if (_findExistingPages && !_dupeReuseRawPages) //find existing entry to point to { primaryPageIndex = _resources.Pages.FindIndex(r => r.Checksum == _container.FindResourcePage(resource.Location.OriginalPrimaryPageIndex).Checksum); } else if (_dupeReuseRawPages) // point back to the original page for edge case duplication { primaryPageIndex = resource.Location.OriginalPrimaryPageIndex; } if (primaryPageIndex == -1) { primaryPageIndex = InjectResourcePage(resource.Location.OriginalPrimaryPageIndex, stream); } newResource.Location.PrimaryPage = _resources.Pages[primaryPageIndex]; } newResource.Location.PrimaryOffset = resource.Location.PrimaryOffset; newResource.Location.PrimarySize = resource.Location.PrimarySize; if (newResource.Location.PrimarySize != null) { newResource.Location.PrimarySize.Index = _resources.Sizes.Count; _resources.Sizes.Add(newResource.Location.PrimarySize); } // Secondary page pointers if (resource.Location.OriginalSecondaryPageIndex >= 0) { int secondaryPageIndex = -1; if (_findExistingPages && !_dupeReuseRawPages) //find existing entry to point to { secondaryPageIndex = _resources.Pages.FindIndex(r => r.Checksum == _container.FindResourcePage(resource.Location.OriginalSecondaryPageIndex).Checksum); } else if (_dupeReuseRawPages) // point back to the original page for edge case duplication { secondaryPageIndex = resource.Location.OriginalSecondaryPageIndex; } if (secondaryPageIndex == -1) { secondaryPageIndex = InjectResourcePage(resource.Location.OriginalSecondaryPageIndex, stream); } newResource.Location.SecondaryPage = _resources.Pages[secondaryPageIndex]; } newResource.Location.SecondaryOffset = resource.Location.SecondaryOffset; newResource.Location.SecondarySize = resource.Location.SecondarySize; if (newResource.Location.SecondarySize != null) { newResource.Location.SecondarySize.Index = _resources.Sizes.Count; _resources.Sizes.Add(newResource.Location.SecondarySize); } // tert page pointers if (resource.Location.OriginalTertiaryPageIndex >= 0) { int tertiaryPageIndex = -1; if (_findExistingPages && !_dupeReuseRawPages) //find existing entry to point to { tertiaryPageIndex = _resources.Pages.FindIndex(r => r.Checksum == _container.FindResourcePage(resource.Location.OriginalTertiaryPageIndex).Checksum); } else if (_dupeReuseRawPages) // point back to the original page for edge case duplication { tertiaryPageIndex = resource.Location.OriginalTertiaryPageIndex; } if (tertiaryPageIndex == -1) { tertiaryPageIndex = InjectResourcePage(resource.Location.OriginalTertiaryPageIndex, stream); } newResource.Location.TertiaryPage = _resources.Pages[tertiaryPageIndex]; } newResource.Location.TertiaryOffset = resource.Location.TertiaryOffset; newResource.Location.TertiarySize = resource.Location.TertiarySize; if (newResource.Location.TertiarySize != null) { newResource.Location.TertiarySize.Index = _resources.Sizes.Count; _resources.Sizes.Add(newResource.Location.TertiarySize); } } newResource.ResourceFixups.AddRange(resource.ResourceFixups); newResource.DefinitionFixups.AddRange(resource.DefinitionFixups); newResource.ResourceBits = resource.ResourceBits; newResource.BaseDefinitionAddress = resource.BaseDefinitionAddress; // Make it load LoadZoneSets(stream); if (_zoneSets != null) { _zoneSets.ExpandAllResources(newResource.Index.Index); if (_zoneSets.GlobalZoneSet != null) { _zoneSets.GlobalZoneSet.ActivateResource(newResource, true); } } return(newIndex); }
private static ExtractedResourceInfo ReadResource(IReader reader, byte version) { if (version > 2) { throw new InvalidOperationException("Unrecognized \"rsrc\" block version"); } var originalIndex = new DatumIndex(reader.ReadUInt32()); var resource = new ExtractedResourceInfo(originalIndex); resource.Flags = reader.ReadUInt32(); resource.Type = reader.ReadAscii(); if (string.IsNullOrEmpty(resource.Type)) { resource.Type = null; } resource.Info = ReadByteArray(reader); resource.OriginalParentTagIndex = new DatumIndex(reader.ReadUInt32()); byte hasLocation = reader.ReadByte(); if (hasLocation != 0) { resource.Location = new ExtractedResourcePointer(); resource.Location.OriginalPrimaryPageIndex = reader.ReadInt32(); resource.Location.PrimaryOffset = reader.ReadInt32(); if (version > 1) { var size = reader.ReadInt32(); if (size != -1) { ResourceSize newSize = new ResourceSize(); newSize.Size = size; byte partCount = reader.ReadByte(); for (int i = 0; i < partCount; i++) { ResourceSizePart newPart = new ResourceSizePart(); newPart.Offset = reader.ReadInt32(); newPart.Size = reader.ReadInt32(); newSize.Parts.Add(newPart); } resource.Location.PrimarySize = newSize; } else { resource.Location.PrimarySize = null; } } else { resource.Location.PrimarySize = null; reader.Skip(4); } resource.Location.OriginalSecondaryPageIndex = reader.ReadInt32(); resource.Location.SecondaryOffset = reader.ReadInt32(); if (version > 1) { var size = reader.ReadInt32(); if (size != -1) { ResourceSize newSize = new ResourceSize(); newSize.Size = size; byte partCount = reader.ReadByte(); for (int i = 0; i < partCount; i++) { ResourceSizePart newPart = new ResourceSizePart(); newPart.Offset = reader.ReadInt32(); newPart.Size = reader.ReadInt32(); newSize.Parts.Add(newPart); } resource.Location.SecondarySize = newSize; } else { resource.Location.SecondarySize = null; } } else { resource.Location.SecondarySize = null; reader.Skip(4); } if (version > 1) { resource.Location.OriginalTertiaryPageIndex = reader.ReadInt32(); resource.Location.TertiaryOffset = reader.ReadInt32(); var size = reader.ReadInt32(); if (size != -1) { ResourceSize newSize = new ResourceSize(); newSize.Size = size; byte partCount = reader.ReadByte(); for (int i = 0; i < partCount; i++) { ResourceSizePart newPart = new ResourceSizePart(); newPart.Offset = reader.ReadInt32(); newPart.Size = reader.ReadInt32(); newSize.Parts.Add(newPart); } resource.Location.TertiarySize = newSize; } else { resource.Location.TertiarySize = null; } } } if (version == 1) { reader.BaseStream.Position += 4; resource.ResourceBits = reader.ReadUInt16(); reader.BaseStream.Position += 2; } else { resource.ResourceBits = reader.ReadInt32(); } resource.BaseDefinitionAddress = reader.ReadInt32(); int numResourceFixups = reader.ReadInt32(); for (int i = 0; i < numResourceFixups; i++) { var fixup = new ResourceFixup(); fixup.Offset = reader.ReadInt32(); fixup.Address = reader.ReadUInt32(); resource.ResourceFixups.Add(fixup); } int numDefinitionFixups = reader.ReadInt32(); for (int i = 0; i < numDefinitionFixups; i++) { var fixup = new ResourceDefinitionFixup(); fixup.Offset = reader.ReadInt32(); fixup.Type = reader.ReadInt32(); resource.DefinitionFixups.Add(fixup); } return(resource); }
/// <summary> /// Adds information about a resource to the container. /// </summary> /// <param name="resource">The resource to add.</param> public void AddResource(ExtractedResourceInfo resource) { _resourcesByIndex[resource.OriginalIndex] = resource; }
private static ExtractedResourceInfo ReadResource(IReader reader, byte version) { if (version != 1) throw new InvalidOperationException("Unrecognized \"rsrc\" block version"); var originalIndex = new DatumIndex(reader.ReadUInt32()); var resource = new ExtractedResourceInfo(originalIndex); resource.Flags = reader.ReadUInt32(); resource.Type = reader.ReadAscii(); if (string.IsNullOrEmpty(resource.Type)) resource.Type = null; resource.Info = ReadByteArray(reader); resource.OriginalParentTagIndex = new DatumIndex(reader.ReadUInt32()); byte hasLocation = reader.ReadByte(); if (hasLocation != 0) { resource.Location = new ExtractedResourcePointer(); resource.Location.OriginalPrimaryPageIndex = reader.ReadInt32(); resource.Location.PrimaryOffset = reader.ReadInt32(); resource.Location.PrimaryUnknown = reader.ReadInt32(); resource.Location.OriginalSecondaryPageIndex = reader.ReadInt32(); resource.Location.SecondaryOffset = reader.ReadInt32(); resource.Location.SecondaryUnknown = reader.ReadInt32(); } resource.Unknown1 = reader.ReadInt32(); resource.Unknown2 = reader.ReadInt32(); resource.Unknown3 = reader.ReadInt32(); int numResourceFixups = reader.ReadInt32(); for (int i = 0; i < numResourceFixups; i++) { var fixup = new ResourceFixup(); fixup.Offset = reader.ReadInt32(); fixup.Address = reader.ReadUInt32(); resource.ResourceFixups.Add(fixup); } int numDefinitionFixups = reader.ReadInt32(); for (int i = 0; i < numDefinitionFixups; i++) { var fixup = new ResourceDefinitionFixup(); fixup.Offset = reader.ReadInt32(); fixup.Type = reader.ReadInt32(); resource.DefinitionFixups.Add(fixup); } return resource; }
public DatumIndex InjectResource(ExtractedResourceInfo resource, IStream stream) { if (_resources == null) { return(DatumIndex.Null); } if (resource == null) { throw new ArgumentNullException("resource is null"); } // Don't inject the resource if it's already been injected DatumIndex newIndex; if (_resourceIndices.TryGetValue(resource, out newIndex)) { return(newIndex); } // Create a new datum index for it (0x4152 = 'AR') and associate it LoadResourceTable(stream); newIndex = new DatumIndex(0x4152, (ushort)_resources.Resources.Count); _resourceIndices[resource] = newIndex; // Create a native resource for it var newResource = new Resource(); _resources.Resources.Add(newResource); newResource.Index = newIndex; newResource.Flags = resource.Flags; newResource.Type = resource.Type; newResource.Info = resource.Info; if (resource.OriginalParentTagIndex.IsValid) { DatumIndex parentTagIndex = InjectTag(resource.OriginalParentTagIndex, stream); newResource.ParentTag = _cacheFile.Tags[parentTagIndex]; } if (resource.Location != null) { newResource.Location = new ResourcePointer(); // Primary page pointers if (resource.Location.OriginalPrimaryPageIndex >= 0) { int primaryPageIndex = InjectResourcePage(resource.Location.OriginalPrimaryPageIndex, stream); newResource.Location.PrimaryPage = _resources.Pages[primaryPageIndex]; } newResource.Location.PrimaryOffset = resource.Location.PrimaryOffset; newResource.Location.PrimaryUnknown = resource.Location.PrimaryUnknown; // Secondary page pointers if (resource.Location.OriginalSecondaryPageIndex >= 0) { int secondaryPageIndex = InjectResourcePage(resource.Location.OriginalSecondaryPageIndex, stream); newResource.Location.SecondaryPage = _resources.Pages[secondaryPageIndex]; } newResource.Location.SecondaryOffset = resource.Location.SecondaryOffset; newResource.Location.SecondaryUnknown = resource.Location.SecondaryUnknown; } newResource.ResourceFixups.AddRange(resource.ResourceFixups); newResource.DefinitionFixups.AddRange(resource.DefinitionFixups); newResource.Unknown1 = resource.Unknown1; newResource.Unknown2 = resource.Unknown2; newResource.Unknown3 = resource.Unknown3; // Make it load LoadZoneSets(stream); if (_zoneSets != null && _zoneSets.GlobalZoneSet != null) { _zoneSets.GlobalZoneSet.ActivateResource(newResource, true); } return(newIndex); }