示例#1
0
        public sealed override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
        {
            if (resourceName == null)
            {
                throw new ArgumentNullException(nameof(resourceName));
            }
            if (resourceName.Length == 0)
            {
                throw new ArgumentException(nameof(resourceName));
            }

            InternalManifestResourceInfo internalManifestResourceInfo = GetEcmaManifestModule().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));
        }
示例#2
0
        public sealed override Stream?GetManifestResourceStream(string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (name.Length == 0)
            {
                throw new ArgumentException(nameof(name));
            }

            InternalManifestResourceInfo internalManifestResourceInfo = GetEcmaManifestModule().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
                {
                    return(GetFile(internalManifestResourceInfo.FileName));
                }
            }
        }
        internal unsafe InternalManifestResourceInfo GetInternalManifestResourceInfo(string resourceName)
        {
            MetadataReader reader = Reader;

            InternalManifestResourceInfo     result            = default;
            ManifestResourceHandleCollection manifestResources = reader.ManifestResources;

            foreach (ManifestResourceHandle resourceHandle in manifestResources)
            {
                ManifestResource resource = resourceHandle.GetManifestResource(reader);
                if (resource.Name.Equals(resourceName, reader))
                {
                    result.Found = true;
                    if (resource.Implementation.IsNil)
                    {
                        checked
                        {
                            // Embedded data resource
                            result.ResourceLocation = ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile;
                            PEReader pe = _guardedPEReader.PEReader;

                            PEMemoryBlock resourceDirectory = pe.GetSectionData(pe.PEHeaders.CorHeader.ResourcesDirectory.RelativeVirtualAddress);
                            BlobReader    blobReader        = resourceDirectory.GetReader((int)resource.Offset, resourceDirectory.Length - (int)resource.Offset);
                            uint          length            = blobReader.ReadUInt32();
                            result.PointerToResource = blobReader.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(int) > blobReader.Length)
                            {
                                throw new BadImageFormatException();
                            }
                            result.SizeOfResource = length;
                        }
                    }
                    else
                    {
                        if (resource.Implementation.Kind == HandleKind.AssemblyFile)
                        {
                            // Get file name
                            result.ResourceLocation = default;
                            AssemblyFile file = ((AssemblyFileHandle)resource.Implementation).GetAssemblyFile(reader);
                            result.FileName = file.Name.GetString(reader);
                            if (file.ContainsMetadata)
                            {
                                EcmaModule module = (EcmaModule)Assembly.GetModule(result.FileName);
                                if (module == null)
                                {
                                    throw new BadImageFormatException(SR.Format(SR.ManifestResourceInfoReferencedBadModule, result.FileName));
                                }
                                result = module.GetInternalManifestResourceInfo(resourceName);
                            }
                        }
                        else if (resource.Implementation.Kind == HandleKind.AssemblyReference)
                        {
                            // Resolve assembly reference
                            result.ResourceLocation = ResourceLocation.ContainedInAnotherAssembly;
                            RoAssemblyName destinationAssemblyName = ((AssemblyReferenceHandle)resource.Implementation).ToRoAssemblyName(reader);
                            result.ReferencedAssembly = Loader.ResolveAssembly(destinationAssemblyName);
                        }
                    }
                }
            }

            return(result);
        }