/// <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); } }
public FileContent(Device.Identification devInfo) { DeviceInfo = devInfo; ImagesByAltSetting = new Dictionary <byte, NamedMemory>(); }