Exemple #1
0
        /// <summary>
        /// Extracts the contents of a DFU file.
        /// </summary>
        /// <param name="filepath">Path to the DFU file</param>
        /// <returns>The device and memory image information</returns>
        public static FileContent ParseFile(string filepath)
        {
            using (BinaryReader reader = new BinaryReader(File.Open(filepath, FileMode.Open)))
            {
                var suffix  = ReadSuffix(reader);
                var devInfo = new Device.Identification(suffix);
                var fc      = new FileContent(devInfo);

                // remove the suffix from the contents
                byte[] content = new byte[reader.BaseStream.Length - suffix.bLength];
                reader.BaseStream.Position = 0;
                reader.Read(content, 0, content.Length);

                // if the protocol version is according to USB spec
                if (fc.DeviceInfo.DfuVersion <= Protocol.LatestVersion)
                {
                    // no name nor address is stored in the file, use whatever
                    var mem = new NamedMemory("default");

                    // the rest of the contents is entirely the firmware
                    mem.TryAddSegment(new Segment(~0ul, content));
                    fc.ImagesByAltSetting.Add(0, mem);
                }
                // if the protocol version is according to STMicroelectronics Extension
                else if (fc.DeviceInfo.DfuVersion == Protocol.SeVersion)
                {
                    long fileOffset = 0;
                    BufferAllocDelegate getDataChunk = (chunkSize) =>
                    {
                        byte[] chunkData = new byte[chunkSize];
                        Array.Copy(content, fileOffset, chunkData, 0, chunkSize);
                        fileOffset += chunkSize;
                        return(chunkData);
                    };

                    // DfuSe prefix
                    var prefix = getDataChunk(SePrefix.Size).ToStruct <SePrefix>();

                    if (prefix.sSignature != SePrefix.Signature)
                    {
                        throw new ArgumentException("The selected dfu file has invalid DfuSe prefix signature.");
                    }

                    // there are a number of targets, each of which is mapped to a different alternate setting
                    for (int tt = 0; tt < prefix.bTargets; tt++)
                    {
                        // image target prefix
                        var target = getDataChunk(SeTargetPrefix.Size).ToStruct <SeTargetPrefix>();

                        if (target.sSignature != SeTargetPrefix.Signature)
                        {
                            throw new ArgumentException("The selected dfu file has invalid DfuSe target prefix signature.");
                        }
                        // TODO
                        //if (!target.bTargetNamed)

                        var nmem = new NamedMemory(target.sTargetName);

                        // each target contains a number of elements (memory segments)
                        for (uint e = 0; e < target.dwNbElements; e++)
                        {
                            var elem = getDataChunk(SeElementHeader.Size).ToStruct <SeElementHeader>();
                            nmem.TryAddSegment(new Segment(elem.dwElementAddress, getDataChunk(elem.dwElementSize)));
                        }

                        // the target's alternate setting is the dictionary index
                        fc.ImagesByAltSetting.Add(target.bAlternateSetting, nmem);
                    }

                    // no leftover data is allowed
                    if ((fileOffset + suffix.bLength) != reader.BaseStream.Length)
                    {
                        throw new ArgumentException(String.Format("The selected dfu file has unprocessed data starting at {0}.", fileOffset));
                    }
                }
                else
                {
                    throw new ArgumentException("The selected dfu file has unsupported DFU specification version.");
                }

                return(fc);
            }
        }
Exemple #2
0
 public FileContent(Device.Identification devInfo)
 {
     DeviceInfo         = devInfo;
     ImagesByAltSetting = new Dictionary <byte, NamedMemory>();
 }