예제 #1
0
        /// <summary>
        /// Loads and validates the image file header.
        /// </summary>
        /// <param name="reader">The reader, to read From.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            this.Signature = reader.ReadUInt32();
            if (this.Signature != PE_SIGNATURE)
                throw new BadImageFormatException();

            this.FileHeader.Read(reader);
            this.OptionalHeader.Read(reader);
        }
        public override void DeserializeOverride(StreamLimiter stream, EventShuttle eventShuttle)
        {
            var typeNode = (CollectionTypeNode)TypeNode;

            /* Create temporary list */
            Type collectionType = typeof(List<>).MakeGenericType(typeNode.ChildType);
            var collection = (IList)Activator.CreateInstance(collectionType);

            /* Create single serializer to do all the work */
            var childSerializer = (ValueValueNode)typeNode.Child.CreateSerializer(this);

            var reader = new EndianAwareBinaryReader(stream, Endianness);
            var childSerializedType = childSerializer.TypeNode.GetSerializedType();

            var count = TypeNode.FieldCountBinding != null ? Convert.ToInt32(TypeNode.FieldCountBinding.GetValue(this)) : int.MaxValue;

            int? itemLength = null;
            if (TypeNode.ItemLengthBinding != null)
                itemLength = Convert.ToInt32(TypeNode.ItemLengthBinding.GetValue(this));

            var terminationValue = typeNode.TerminationValue;
            var terminationChild = typeNode.TerminationChild == null ? null : typeNode.TerminationChild.CreateSerializer(this);

            int itemCount = 0;
            for (int i = 0; i < count; i++)
            {
                if (ShouldTerminate(stream))
                    break;

                /* Check termination case */
                if (terminationChild != null)
                {
                    using (var streamResetter = new StreamResetter(stream))
                    {
                        terminationChild.Deserialize(stream, eventShuttle);

                        if (terminationChild.Value.Equals(terminationValue))
                        {
                            streamResetter.CancelReset();
                            break;
                        }
                    }
                }

                var value = childSerializer.Deserialize(reader, childSerializedType, itemLength);
                collection.Add(value);

                itemCount++;
            }

            /* Create final collection */
            Value = CreateCollection(itemCount);

            /* Copy temp list into final collection */
            for (int i = 0; i < itemCount; i++)
                SetCollectionValue(collection[i], i);
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PortableExecutableImage"/> class.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="codeBase">The code base.</param>
        public PortableExecutableImage(Stream stream)
        {
            // Check preconditions
            if (stream == null)
                throw new ArgumentNullException("stream");

            assemblyStream = stream;
            assemblyReader = new EndianAwareBinaryReader(stream, true);

            // Load all headers by visiting them sequentially
            dosHeader.Read(assemblyReader);

            assemblyReader.BaseStream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
            ntHeader.Read(assemblyReader);

            if (CLI_HEADER_DATA_DIRECTORY >= ntHeader.OptionalHeader.NumberOfRvaAndSizes)
                throw new BadImageFormatException();

            sections = new ImageSectionHeader[ntHeader.FileHeader.NumberOfSections];
            for (int i = 0; i < ntHeader.FileHeader.NumberOfSections; i++)
                sections[i].Read(assemblyReader);

            long position = ResolveVirtualAddress(ntHeader.OptionalHeader.DataDirectory[CLI_HEADER_DATA_DIRECTORY].VirtualAddress);
            assemblyReader.BaseStream.Seek(position, SeekOrigin.Begin);
            cliHeader.Read(assemblyReader);

            // Load the provider...
            position = ResolveVirtualAddress(cliHeader.Metadata.VirtualAddress);
            assemblyReader.BaseStream.Position = position;
            metadata = assemblyReader.ReadBytes(cliHeader.Metadata.Size);

            metadataRoot = new MetadataRoot(metadata);
        }
예제 #4
0
 /// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 void IDisposable.Dispose()
 {
     if (null != assemblyReader)
         assemblyReader.Close();
     assemblyReader = null;
     assemblyStream = null;
 }
예제 #5
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        private MethodHeader ReadMethodHeader(EndianAwareBinaryReader reader)
        {
            MethodHeader header = new MethodHeader();

            // Read first byte
            header.Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (header.Flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    header.CodeSize = ((uint)(header.Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    header.Flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    // Read second byte of flags
                    header.Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)header.Flags);
                    if (MethodFlags.ValidHeader != (header.Flags & MethodFlags.HeaderSizeMask))
                        throw new InvalidDataException(@"Invalid method header.");
                    header.MaxStack = reader.ReadUInt16();
                    header.CodeSize = reader.ReadUInt32();
                    header.LocalsSignature = new Token(reader.ReadUInt32()); // ReadStandAloneSigRow
                    break;

                default:
                    throw new InvalidDataException(@"Invalid method header while trying to decode " + this.methodCompiler.Method.ToString() + ". (Flags = " + header.Flags.ToString("X") + ", Rva = " + this.methodCompiler.Method.Rva + ")");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (header.Flags & MethodFlags.MoreSections))
                return header;

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + header.CodeSize;
            if (0 != (dataSectPos & 3))
                dataSectPos += (4 - (dataSectPos % 4));
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int length;
                int blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), @"Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    methodCompiler.ExceptionClauseHeader.AddClause(clause);
                }
            }
            while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;

            return header;
        }
예제 #6
0
        /// <summary>
        /// Performs stage specific processing on the compiler context.
        /// </summary>
        void IMethodCompilerStage.Run()
        {
            if (plugSystem != null)
            {
                RuntimeMethod plugMethod = plugSystem.GetPlugMethod(this.methodCompiler.Method);

                if (plugMethod != null)
                {
                    SymbolOperand plugSymbol = SymbolOperand.FromMethod(plugMethod);

                    Context ctx = new Context(instructionSet);
                    ctx.AppendInstruction(IR.IRInstruction.Jmp, null, plugSymbol);
                    ctx.Label = -1;
                    basicBlocks.CreateBlock(BasicBlock.PrologueLabel, ctx.Index);

                    return;
                }
            }

            using (Stream code = methodCompiler.GetInstructionStream())
            {
                using (codeReader = new EndianAwareBinaryReader(code, true))
                {
                    MethodHeader header = ReadMethodHeader(codeReader);

                    if (header.LocalsSignature.RID != 0)
                    {
                        StandAloneSigRow row = methodCompiler.Method.Module.MetadataModule.Metadata.ReadStandAloneSigRow(header.LocalsSignature);

                        LocalVariableSignature localsSignature;

                        if (methodCompiler.Method.DeclaringType is CilGenericType)
                        {
                            localsSignature = new LocalVariableSignature(methodCompiler.Method.Module.MetadataModule.Metadata, row.SignatureBlobIdx, (methodCompiler.Method.DeclaringType as CilGenericType).GenericArguments);
                        }
                        else
                        {
                            localsSignature = new LocalVariableSignature(methodCompiler.Method.Module.MetadataModule.Metadata, row.SignatureBlobIdx);
                        }

                        var declaringType = this.methodCompiler.Method.DeclaringType;
                        var locals = localsSignature.Locals;
                        for (var i = 0; i < locals.Length; ++i)
                        {
                            var local = locals[i];
                            if (local.Type is GenericInstSigType && declaringType is CilGenericType)
                            {
                                var genericInstSigType = local.Type as GenericInstSigType;
                                var genericArguments = methodCompiler.AssemblyCompiler.GenericTypePatcher.CloseGenericArguments((declaringType as CilGenericType).GenericArguments, genericInstSigType.GenericArguments);
                                local = new VariableSignature(locals[i], genericArguments);
                            }
                        }

                        methodCompiler.SetLocalVariableSignature(localsSignature);
                    }

                    /* Decode the instructions */
                    Decode(methodCompiler, header);
                }
            }
        }
예제 #7
0
파일: Header.cs 프로젝트: tea/MOSA-Project
        /// <summary>
        /// Reads the specified reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            Ident = reader.ReadBytes(16);

            // Check for magic number
            if (Ident[0] != MagicNumber[0] || Ident[1] != MagicNumber[1] || Ident[2] != MagicNumber[2] || Ident[3] != MagicNumber[3])
            {
                // Magic number not present, so it seems to be an invalid ELF file
                throw new NotSupportedException("This is not a valid ELF file");
            }

            Type = (FileType)reader.ReadUInt16();
            Machine = (MachineType)reader.ReadUInt16();
            Version = (Version)reader.ReadUInt32();
            EntryAddress = reader.ReadUInt32();
            ProgramHeaderOffset = reader.ReadUInt32();
            SectionHeaderOffset = reader.ReadUInt32();
            Flags = reader.ReadUInt32();
            ElfHeaderSize = reader.ReadUInt16();
            ProgramHeaderEntrySize = reader.ReadUInt16();
            ProgramHeaderNumber = reader.ReadUInt16();
            SectionHeaderEntrySize = reader.ReadUInt16();
            SectionHeaderNumber = reader.ReadUInt16();
            SectionHeaderStringIndex = reader.ReadUInt16();
        }
예제 #8
0
        public static void PatchSyslinux_6_03(PartitionDevice partitionDevice, FatFileSystem fat)
        {
            // Locate ldlinux.sys file for patching
            string filename = "ldlinux.sys";
            string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

            var location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

            if (!location.IsValid)
                throw new InvalidProgramException("Unable to find syslinux.sys");

            // Get the file size & number of sectors used
            uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);

            var sectors = new List<uint>();

            // Create list of the sectors of the file
            for (uint cluster = location.FirstCluster; (cluster != 0); cluster = fat.GetNextCluster(cluster))
            {
                uint sec = fat.GetSectorByCluster(cluster);
                for (uint i = 0; i < fat.SectorsPerCluster; i++)
                {
                    sectors.Add(sec + i);
                }
            }

            // Get the ldlinux.sys file stream
            var ldlinux = new FatFileStream(fat, location);

            var ldlinuxReader = new EndianAwareBinaryReader(ldlinux, Endianness.Little);

            // Search for 0x3EB202FE (magic)
            while ((ldlinuxReader.ReadUInt32() != Syslinux.LDLINUX_MAGIC) && (ldlinux.Position < ldlinux.Length)) ;

            if (ldlinux.Position >= ldlinux.Length || ldlinux.Position <= 0)
                throw new InvalidProgramException("Unable to find patch location for syslinux");

            uint patchArea = (uint)ldlinux.Position - 4;

            // Get Extended Patch Area offset
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.EPAOffset;
            ushort epa = ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr0;
            uint sect1Ptr0 = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.Sect1Ptr1;
            uint sect1Ptr1 = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrOffset;
            uint ex = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.SecPtrCnt;
            uint nptrs = (uint)ldlinuxReader.ReadUInt16();

            ldlinux.Position = epa + Syslinux.ExtendedPatchAreaOffset.AdvPtrOffset;
            uint advptrs = (uint)ldlinuxReader.ReadUInt16();

            if (sectors.Count > nptrs)
                throw new InvalidProgramException("Insufficient space for patching syslinux");

            var ldlinuxWriter = new EndianAwareBinaryWriter(ldlinux, Endianness.Little);

            // Set up the totals
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)sectors.Count);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((ushort)2);

            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.DataSectors;
            ldlinuxWriter.Write((uint)fileSize >> 2);

            // Generate Extents
            var extents = GenerateExtents(sectors);

            ldlinux.Position = ex;

            // Write out extents
            foreach (var extent in extents)
            {
                ldlinuxWriter.Write((ulong)extent.Start);
                ldlinuxWriter.Write((ushort)extent.Length);
            }

            // Write out ADV
            ldlinux.Position = advptrs;
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 2]);
            ldlinuxWriter.Write((ulong)sectors[sectors.Count - 1]);

            // Clear out checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write((uint)0);

            // Write back the updated cluster
            ldlinuxWriter.Flush();

            // Re-Calculate checksum
            ldlinux.Position = 0;
            uint csum = Syslinux.LDLINUX_MAGIC;
            for (uint index = 0; index < (ldlinux.Length >> 2); index++)
            {
                csum = csum + ldlinuxReader.ReadUInt32();
            }

            // Set the checksum
            ldlinux.Position = patchArea + Syslinux.PatchAreaOffset.Checksum;
            ldlinuxWriter.Write(csum);

            // Write patched cluster back to disk
            ldlinuxWriter.Flush();

            // Read boot sector
            var fatBootSector = new BinaryFormat(partitionDevice.ReadBlock(0, 1));

            // Set the first sector location of the file
            fatBootSector.SetUInt(sect1Ptr0, fat.GetSectorByCluster(location.FirstCluster));
            fatBootSector.SetUInt(sect1Ptr1, 0);   // since only 32-bit offsets are support, the high portion of 64-bit value is zero

            // Write back patched boot sector
            partitionDevice.WriteBlock(0, 1, fatBootSector.Data);
        }
예제 #9
0
파일: Linker.cs 프로젝트: tea/MOSA-Project
        private uint CalculateChecksum(string file)
        {
            uint csum = 0;

            using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (BinaryReader reader = new EndianAwareBinaryReader(stream, true))
                {
                    uint l = (uint)stream.Length;
                    for (uint p = 0; p < l; p += 2)
                    {
                        csum += reader.ReadUInt16();
                        if (csum > 0x0000FFFF)
                        {
                            csum = (csum & 0xFFFF) + (csum >> 16);
                        }
                    }

                    csum = (csum & 0xFFFF) + (csum >> 16);
                    csum += l;
                }
            }

            return csum;
        }
예제 #10
0
    /// <summary>
    /// 
    /// </summary>
    /// <param name="bytController"></param>
    /// <param name="cntlMsgs"></param>
    /// <param name="strControllerData"></param>
    public static void DecodeControllerData(byte[] bytController, ref ControllerMessages cntlMsgs)
    {
        //UnityEngine.Debug.Log("Entered DecodeControllerData()");
        int intMsgType = 0;

        MemoryStream stream = new MemoryStream(bytController);
        using (EndianAwareBinaryReader reader = new EndianAwareBinaryReader(stream, false))
        {
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                intMsgType = reader.ReadInt32();
                //UnityEngine.Debug.Log("intMsgType = " + intMsgType);

                if (intMsgType == ViewerConstants.MESSAGE_TOUCH_INPUT)
                {
                    UnityEngine.Debug.Log("reading touch");
                    cntlMsgs.TouchMessage.X = reader.ReadSingle();
                    cntlMsgs.TouchMessage.Y = reader.ReadSingle();
                    cntlMsgs.TouchMessage.Timestamp = reader.ReadInt64();
                    cntlMsgs.TouchMessage.Pointer = reader.ReadInt32();
                    cntlMsgs.TouchMessage.Active = reader.ReadInt32();
                }
                else if (intMsgType == ViewerConstants.MESSAGE_ACCELEROMETER_INPUT)
                {
                    //UnityEngine.Debug.Log("reading accel");
                    cntlMsgs.AccelMessage.X = reader.ReadSingle();
                    cntlMsgs.AccelMessage.Y = reader.ReadSingle();
                    cntlMsgs.AccelMessage.Z = reader.ReadSingle();
                    cntlMsgs.AccelMessage.Timestamp = reader.ReadInt32();
                }
                else if (intMsgType == ViewerConstants.MESSAGE_MAGNOTOMETER_INPUT)
                {
                    //UnityEngine.Debug.Log("reading magnotometer");
                    cntlMsgs.MagnoMessage.X = reader.ReadSingle();
                    cntlMsgs.MagnoMessage.Y = reader.ReadSingle();
                    cntlMsgs.MagnoMessage.Z = reader.ReadSingle();
                    cntlMsgs.MagnoMessage.Timestamp = reader.ReadInt32();
                }
                else if (intMsgType == ViewerConstants.MESSAGE_ATTITUDE_INPUT)
                {
                    //UnityEngine.Debug.Log("reading attitude");
                    cntlMsgs.AttMessage.X = reader.ReadSingle();
                    cntlMsgs.AttMessage.Y = reader.ReadSingle();
                    cntlMsgs.AttMessage.Z = reader.ReadSingle();
                    cntlMsgs.AttMessage.Timestamp = reader.ReadInt32();
                }

                else if (intMsgType == ViewerConstants.MESSAGE_TRACKBALL_INPUT)
                {
                    UnityEngine.Debug.Log("reading trackball");
                    cntlMsgs.TrackMessage.X = reader.ReadSingle();
                    cntlMsgs.TrackMessage.Y = reader.ReadSingle();
                }
                else if (intMsgType == ViewerConstants.MESSAGE_OPTIONS)
                {
                    UnityEngine.Debug.Log("reading options");
                    cntlMsgs.OptionMessage.ScreenWidth = reader.ReadInt32();
                    cntlMsgs.OptionMessage.ScreenHeight = reader.ReadInt32();
                }
                else if (intMsgType == ViewerConstants.MESSAGE_KEY)
                {
                    UnityEngine.Debug.Log("reading keys");
                    cntlMsgs.KeyMessage.State = reader.ReadInt32();
                    cntlMsgs.KeyMessage.Key = reader.ReadInt32();
                    cntlMsgs.KeyMessage.Unicode = reader.ReadInt32();
                }
            }
        }
    }
예제 #11
0
            public Vector3 Scale; //!< Scaling information

            #endregion Fields

            #region Methods

            /// <summary>
            /// Load a mesh from a stream
            /// </summary>
            /// <param name="filename">Filename and path of the file containing the reference mesh</param>
            public virtual void LoadMesh(string filename)
            {
                using(FileStream meshStream = new FileStream(filename, FileMode.Open, FileAccess.Read))
                using (EndianAwareBinaryReader reader = new EndianAwareBinaryReader(meshStream))
                {
                    Header = TrimAt0(reader.ReadString(24));
                    if (!String.Equals(Header, MeshHeader))
                        throw new FileLoadException("Unrecognized mesh format");

                    // Populate base mesh parameters
                    HasWeights = (reader.ReadByte() != 0);
                    HasDetailTexCoords = (reader.ReadByte() != 0);
                    Position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    RotationAngles = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    RotationOrder = reader.ReadByte();
                    Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    NumFaces = reader.ReadUInt16();

                    Faces = new Face[NumFaces];

                    for (int i = 0; i < NumFaces; i++)
                        Faces[i].Indices = new[] { reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16() };
                }
            }
예제 #12
0
        /// <summary>
        /// Load the mesh from a stream
        /// </summary>
        /// <param name="filename">The filename and path of the file containing the mesh data</param>
        public virtual void LoadMesh(string filename)
        {
            using(FileStream meshData = new FileStream(filename, FileMode.Open, FileAccess.Read))
            using (EndianAwareBinaryReader reader = new EndianAwareBinaryReader(meshData))
            {
                Header = TrimAt0(reader.ReadString(24));
                if (!String.Equals(Header, MeshHeader))
                    throw new FileLoadException("Unrecognized mesh format");

                // Populate base mesh parameters
                HasWeights = (reader.ReadByte() != 0);
                HasDetailTexCoords = (reader.ReadByte() != 0);
                Position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                RotationAngles = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                /* RotationOrder = */ reader.ReadByte();
                Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                // Populate the vertex array
                NumVertices = reader.ReadUInt16();
                Vertices = new Vertex[NumVertices];
                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                for (int i = 0; i < NumVertices; i++)
                    Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                if (HasDetailTexCoords)
                {
                    for (int i = 0; i < NumVertices; i++)
                        Vertices[i].DetailTexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                }

                if (HasWeights)
                {
                    for (int i = 0; i < NumVertices; i++)
                        Vertices[i].Weight = reader.ReadSingle();
                }

                NumFaces = reader.ReadUInt16();
                Faces = new Face[NumFaces];

                for (int i = 0; i < NumFaces; i++)
                    Faces[i].Indices = new[] { reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16() };

                if (HasWeights)
                {
                    NumSkinJoints = reader.ReadUInt16();
                    SkinJoints = new string[NumSkinJoints];

                    for (int i = 0; i < NumSkinJoints; i++)
                    {
                        SkinJoints[i] = TrimAt0(reader.ReadString(64));
                    }
                }
                else
                {
                    NumSkinJoints = 0;
                    SkinJoints = new string[0];
                }

                // Grab morphs
                List<Morph> morphs = new List<Morph>();
                string morphName = TrimAt0(reader.ReadString(64));

                while (morphName != MorphFooter)
                {
                    if (reader.BaseStream.Position + 48 >= reader.BaseStream.Length)
                        throw new FileLoadException("Encountered end of file while parsing morphs");

                    Morph morph = new Morph();
                    morph.Name = morphName;
                    morph.NumVertices = reader.ReadInt32();
                    morph.Vertices = new MorphVertex[morph.NumVertices];

                    for (int i = 0; i < morph.NumVertices; i++)
                    {
                        morph.Vertices[i].VertexIndex = reader.ReadUInt32();
                        morph.Vertices[i].Coord = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].Normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].BiNormal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        morph.Vertices[i].TexCoord = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    }

                    morphs.Add(morph);

                    // Grab the next name
                    morphName = TrimAt0(reader.ReadString(64));
                }

                Morphs = morphs.ToArray();

                // Check if there are remaps or if we're at the end of the file
                if (reader.BaseStream.Position < reader.BaseStream.Length - 1)
                {
                    NumRemaps = reader.ReadInt32();
                    VertexRemaps = new VertexRemap[NumRemaps];

                    for (int i = 0; i < NumRemaps; i++)
                    {
                        VertexRemaps[i].RemapSource = reader.ReadInt32();
                        VertexRemaps[i].RemapDestination = reader.ReadInt32();
                    }
                }
                else
                {
                    NumRemaps = 0;
                    VertexRemaps = new VertexRemap[0];
                }
            }

            // uncompress the skin weights
            if (Skeleton != null)
            {
                // some meshes aren't weighted, which doesn't make much sense.
                // we check for left and right eyeballs, and assign them a 100%
                // to their respective bone
                List<string> expandedJointList = Skeleton.BuildExpandedJointList(SkinJoints);
                if (expandedJointList.Count == 0)
                {
                    if (Name == "eyeBallLeftMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeLeft", "mSkull" });
                    }
                    else if (Name == "eyeBallRightMesh")
                    {
                        expandedJointList.AddRange(new[] { "mEyeRight", "mSkull" });
                    }
                }

                if (expandedJointList.Count > 0)
                    ExpandCompressedSkinWeights(expandedJointList);
            }
        }
예제 #13
0
        /// <summary>
        /// Loads and validates the DOS header.
        /// </summary>
        public void Read(EndianAwareBinaryReader reader)
        {
            e_magic = reader.ReadUInt16();
            e_cblp = reader.ReadUInt16();
            e_cp = reader.ReadUInt16();
            e_crlc = reader.ReadUInt16();
            e_cparhdr = reader.ReadUInt16();
            e_minalloc = reader.ReadUInt16();
            e_maxalloc = reader.ReadUInt16();
            e_ss = reader.ReadUInt16();
            e_sp = reader.ReadUInt16();
            e_csum = reader.ReadUInt16();
            e_ip = reader.ReadUInt16();
            e_cs = reader.ReadUInt16();
            e_lfarlc = reader.ReadUInt16();
            e_ovno = reader.ReadUInt16();
            e_res00 = reader.ReadUInt16();
            e_res01 = reader.ReadUInt16();
            e_res02 = reader.ReadUInt16();
            e_res03 = reader.ReadUInt16();
            e_oemid = reader.ReadUInt16();
            e_oeminfo = reader.ReadUInt16();
            e_res20 = reader.ReadUInt16();
            e_res21 = reader.ReadUInt16();
            e_res22 = reader.ReadUInt16();
            e_res23 = reader.ReadUInt16();
            e_res24 = reader.ReadUInt16();
            e_res25 = reader.ReadUInt16();
            e_res26 = reader.ReadUInt16();
            e_res27 = reader.ReadUInt16();
            e_res28 = reader.ReadUInt16();
            e_res29 = reader.ReadUInt16();
            e_lfanew = reader.ReadUInt32();

            if (DOS_HEADER_MAGIC != e_magic)
                throw new BadImageFormatException();
        }
예제 #14
0
 /// <summary>
 /// Loads the IMAGE_DATA_DIRECTORY from the reader.
 /// </summary>
 /// <param name="reader">The reader.</param>
 public void Read(EndianAwareBinaryReader reader)
 {
     VirtualAddress = reader.ReadUInt32();
     Size = reader.ReadInt32();
 }
예제 #15
0
 /// <summary>
 /// Loads the CLI_HEADER from the reader.
 /// </summary>
 /// <param name="reader">The reader.</param>
 public void Read(EndianAwareBinaryReader reader)
 {
     Cb = reader.ReadUInt32();
     MajorRuntimeVersion = reader.ReadUInt16();
     MinorRuntimeVersion = reader.ReadUInt16();
     Metadata.Read(reader);
     Flags = (RuntimeImageFlags)reader.ReadUInt32();
     EntryPointToken = reader.ReadUInt32();
     Resources.Read(reader);
     StrongNameSignature.Read(reader);
     CodeManagerTable.Read(reader);
     VTableFixups.Read(reader);
     ExportAddressTableJumps.Read(reader);
     ManagedNativeHeader.Read(reader);
 }