Exemple #1
0
        private object?LoadObjectV1(int dataOffset)
        {
            Debug.Assert(System.Threading.Monitor.IsEntered(reader));
            reader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin);
            int typeIndex = reader.Read7BitEncodedInt();

            if (typeIndex == -1)
            {
                return(null);
            }
            string typeName = FindType(typeIndex);
            int    comma    = typeName.IndexOf(',');

            if (comma > 0)
            {
                // strip assembly name
                typeName = typeName.Substring(0, comma);
            }
            switch (typeName)
            {
            case "System.String":
                return(reader.ReadString());

            case "System.Byte":
                return(reader.ReadByte());

            case "System.SByte":
                return(reader.ReadSByte());

            case "System.Int16":
                return(reader.ReadInt16());

            case "System.UInt16":
                return(reader.ReadUInt16());

            case "System.Int32":
                return(reader.ReadInt32());

            case "System.UInt32":
                return(reader.ReadUInt32());

            case "System.Int64":
                return(reader.ReadInt64());

            case "System.UInt64":
                return(reader.ReadUInt64());

            case "System.Single":
                return(reader.ReadSingle());

            case "System.Double":
                return(reader.ReadDouble());

            case "System.DateTime":
                // Ideally we should use DateTime's ToBinary & FromBinary,
                // but we can't for compatibility reasons.
                return(new DateTime(reader.ReadInt64()));

            case "System.TimeSpan":
                return(new TimeSpan(reader.ReadInt64()));

            case "System.Decimal":
                int[] bits = new int[4];
                for (int i = 0; i < bits.Length; i++)
                {
                    bits[i] = reader.ReadInt32();
                }
                return(new decimal(bits));

            default:
                return(new ResourceSerializedObject(FindType(typeIndex), this, reader.BaseStream.Position));
            }
        }
Exemple #2
0
        public ResourcesFile(Stream stream, bool leaveOpen = true)
        {
            fileStartPosition = stream.Position;
            reader            = new MyBinaryReader(stream, leaveOpen);

            const string ResourcesHeaderCorrupted = "Resources header corrupted.";

            // Read ResourceManager header
            // Check for magic number
            int magicNum = reader.ReadInt32();

            if (magicNum != MagicNumber)
            {
                throw new BadImageFormatException("Not a .resources file - invalid magic number");
            }
            // Assuming this is ResourceManager header V1 or greater, hopefully
            // after the version number there is a number of bytes to skip
            // to bypass the rest of the ResMgr header. For V2 or greater, we
            // use this to skip to the end of the header
            int resMgrHeaderVersion = reader.ReadInt32();
            int numBytesToSkip      = reader.ReadInt32();

            if (numBytesToSkip < 0 || resMgrHeaderVersion < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }
            if (resMgrHeaderVersion > 1)
            {
                reader.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current);
            }
            else
            {
                // We don't care about numBytesToSkip; read the rest of the header

                // readerType:
                reader.ReadString();
                // resourceSetType:
                reader.ReadString();
            }

            // Read RuntimeResourceSet header
            // Do file version check
            version = reader.ReadInt32();
            if (version != ResourceSetVersion && version != 1)
            {
                throw new BadImageFormatException($"Unsupported resource set version: {version}");
            }

            numResources = reader.ReadInt32();
            if (numResources < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }

            // Read type positions into type positions array.
            // But delay initialize the type table.
            int numTypes = reader.ReadInt32();

            if (numTypes < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }
            typeTable = new string[numTypes];
            for (int i = 0; i < numTypes; i++)
            {
                typeTable[i] = reader.ReadString();
            }

            // Prepare to read in the array of name hashes
            //  Note that the name hashes array is aligned to 8 bytes so
            //  we can use pointers into it on 64 bit machines. (4 bytes
            //  may be sufficient, but let's plan for the future)
            //  Skip over alignment stuff.  All public .resources files
            //  should be aligned   No need to verify the byte values.
            long pos        = reader.BaseStream.Position - fileStartPosition;
            int  alignBytes = unchecked ((int)pos) & 7;

            if (alignBytes != 0)
            {
                for (int i = 0; i < 8 - alignBytes; i++)
                {
                    reader.ReadByte();
                }
            }

            // Skip over the array of name hashes
            try
            {
                reader.Seek(checked (4 * numResources), SeekOrigin.Current);
            }
            catch (OverflowException)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }

            // Read in the array of relative positions for all the names.
            namePositions = new int[numResources];
            for (int i = 0; i < numResources; i++)
            {
                int namePosition = reader.ReadInt32();
                if (namePosition < 0)
                {
                    throw new BadImageFormatException(ResourcesHeaderCorrupted);
                }
                namePositions[i] = namePosition;
            }

            // Read location of data section.
            int dataSectionOffset = reader.ReadInt32();

            if (dataSectionOffset < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }

            // Store current location as start of name section
            nameSectionPosition = reader.BaseStream.Position;
            dataSectionPosition = fileStartPosition + dataSectionOffset;

            // _nameSectionOffset should be <= _dataSectionOffset; if not, it's corrupt
            if (dataSectionPosition < nameSectionPosition)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }
        }