public sealed override ManifestResourceInfo GetManifestResourceInfo(string resourceName) { if (resourceName == null) { throw new ArgumentNullException(nameof(resourceName)); } if (resourceName.Equals("")) { throw new ArgumentException(nameof(resourceName)); } InternalManifestResourceInfo internalManifestResourceInfo = GetInternalManifestResourceInfo(resourceName); if (internalManifestResourceInfo.ResourceLocation == ResourceLocation.ContainedInAnotherAssembly) { // Must get resource info from other assembly, and OR in the contained in another assembly information ManifestResourceInfo underlyingManifestResourceInfo = internalManifestResourceInfo.ReferencedAssembly.GetManifestResourceInfo(resourceName); internalManifestResourceInfo.FileName = underlyingManifestResourceInfo.FileName; internalManifestResourceInfo.ResourceLocation = underlyingManifestResourceInfo.ResourceLocation | ResourceLocation.ContainedInAnotherAssembly; if (underlyingManifestResourceInfo.ReferencedAssembly != null) { internalManifestResourceInfo.ReferencedAssembly = underlyingManifestResourceInfo.ReferencedAssembly; } } return(new ManifestResourceInfo(internalManifestResourceInfo.ReferencedAssembly, internalManifestResourceInfo.FileName, internalManifestResourceInfo.ResourceLocation)); }
public sealed override Stream GetManifestResourceStream(string name) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (name.Equals("")) { throw new ArgumentException(nameof(name)); } InternalManifestResourceInfo internalManifestResourceInfo = GetInternalManifestResourceInfo(name); if ((internalManifestResourceInfo.ResourceLocation & ResourceLocation.Embedded) != 0) { unsafe { return(new UnmanagedMemoryStream(internalManifestResourceInfo.PointerToResource, internalManifestResourceInfo.SizeOfResource)); } } else { if (internalManifestResourceInfo.ResourceLocation == ResourceLocation.ContainedInAnotherAssembly) { return(internalManifestResourceInfo.ReferencedAssembly.GetManifestResourceStream(name)); } else { // Linked resource case. // TODO Implement linked resources, when FileStream, and CodeBase are fully implemented throw new NotImplementedException(); } } }
private unsafe InternalManifestResourceInfo GetInternalManifestResourceInfo(string resourceName) { InternalManifestResourceInfo result = new InternalManifestResourceInfo(); ManifestResourceHandleCollection manifestResources = MetadataReader.ManifestResources; foreach (var resourceHandle in manifestResources) { ManifestResource resource = MetadataReader.GetManifestResource(resourceHandle); if (MetadataReader.StringComparer.Equals(resource.Name, resourceName)) { result.Found = true; if (resource.Implementation.IsNil) { checked { // Embedded data resource result.ResourceLocation = ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile; PEReader pe = PEReader; PEMemoryBlock resourceDirectory = pe.GetSectionData(pe.PEHeaders.CorHeader.ResourcesDirectory.RelativeVirtualAddress); BlobReader reader = resourceDirectory.GetReader((int)resource.Offset, resourceDirectory.Length - (int)resource.Offset); uint length = reader.ReadUInt32(); result.PointerToResource = reader.CurrentPointer; // Length check the size of the resource to ensure it fits in the PE file section, note, this is only safe as its in a checked region if (length + sizeof(Int32) > reader.Length) { throw new BadImageFormatException(); } result.SizeOfResource = length; } } else { if (resource.Implementation.Kind == HandleKind.AssemblyFile) { // Get file name result.ResourceLocation = default(ResourceLocation); AssemblyFile file = MetadataReader.GetAssemblyFile((AssemblyFileHandle)resource.Implementation); if (file.ContainsMetadata) { result.ResourceLocation = ResourceLocation.Embedded; throw new PlatformNotSupportedException(); // Support for multi-module assemblies is not implemented on this platform } result.FileName = MetadataReader.GetString(file.Name); } else if (resource.Implementation.Kind == HandleKind.AssemblyReference) { // Resolve assembly reference result.ResourceLocation = ResourceLocation.ContainedInAnotherAssembly; RuntimeAssemblyName destinationAssemblyName = ((AssemblyReferenceHandle)resource.Implementation).ToRuntimeAssemblyName(MetadataReader); result.ReferencedAssembly = RuntimeAssembly.GetRuntimeAssemblyIfExists(destinationAssemblyName); } } } } return(result); }