Exemple #1
0
        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);
        }
Exemple #5
0
 /// <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);
        }
Exemple #8
0
		/// <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;
		}