Skip to content

Commit d95e314

Browse files
committed
Dfu: add ParseFileInfo which only verifies the file and extracts the device information
Signed-off-by: Benedek Kupper <kupper.benedek@gmail.com>
1 parent 29f229a commit d95e314

File tree

2 files changed

+57
-31
lines changed

2 files changed

+57
-31
lines changed

Dfu/Device.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ public Identification(ushort vendorId, ushort productId, ushort bcdProductVersio
5050
ProductVersion = new Version(bcdProductVersion >> 8, bcdProductVersion & 0xff);
5151
DfuVersion = new Version(bcdDfuVersion >> 8, bcdDfuVersion & 0xff);
5252
}
53+
54+
internal Identification(FileFormat.Dfu.Suffix dfuSuffix)
55+
: this(dfuSuffix.idVendor, dfuSuffix.idProduct, dfuSuffix.bcdDevice, dfuSuffix.bcdDFU)
56+
{
57+
}
5358
}
5459

5560
/// <summary>

FileFormat/Dfu.cs

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static bool IsExtensionSupported(string ext)
2929
/// allow the host software to detect and prevent attempts to download incompatible firmware.
3030
/// </summary>
3131
[StructLayout(LayoutKind.Sequential, Pack = 1)]
32-
private struct Suffix
32+
internal struct Suffix
3333
{
3434
/// <summary>
3535
/// Total size of this structure in bytes.
@@ -195,52 +195,73 @@ public class FileContent
195195
public Device.Identification DeviceInfo { get; private set; }
196196
public Dictionary<byte, NamedMemory> ImagesByAltSetting { get; private set; }
197197

198-
public FileContent(ushort vendorId, ushort productId, ushort bcdProductVersion, ushort bcdDfuVersion)
198+
public FileContent(Device.Identification devInfo)
199199
{
200-
DeviceInfo = new Device.Identification(vendorId, productId, bcdProductVersion, bcdDfuVersion);
200+
DeviceInfo = devInfo;
201201
ImagesByAltSetting = new Dictionary<byte, NamedMemory>();
202202
}
203203
}
204204

205+
private static Suffix ReadSuffix(BinaryReader reader)
206+
{
207+
// this is the part of the file that the CRC is calculated on
208+
byte[] content = new byte[reader.BaseStream.Length - 4];
209+
reader.BaseStream.Position = 0;
210+
reader.Read(content, 0, content.Length);
211+
212+
byte[] suffixdata = new byte[Suffix.Size];
213+
reader.BaseStream.Position = reader.BaseStream.Length - Suffix.Size;
214+
reader.Read(suffixdata, 0, Suffix.Size);
215+
var suffix = suffixdata.ToStruct<Suffix>();
216+
217+
// verify suffix
218+
if (suffix.dwCRC != Crc32.Calculate(content))
219+
{
220+
throw new ArgumentException("The selected dfu file has invalid CRC.");
221+
}
222+
if (suffix.bLength < Suffix.Size)
223+
{
224+
throw new ArgumentException("The selected dfu file has invalid suffix length.");
225+
}
226+
if (suffix.sDfuSignature != Suffix.Signature)
227+
{
228+
throw new ArgumentException("The selected dfu file has invalid suffix signature.");
229+
}
230+
231+
return suffix;
232+
}
233+
234+
/// <summary>
235+
/// Extracts the device and firmware version information of a DFU file.
236+
/// </summary>
237+
/// <param name="filepath">Path to the DFU file</param>
238+
/// <returns>The device and image version information</returns>
239+
public static Device.Identification ParseFileInfo(string filepath)
240+
{
241+
using (BinaryReader reader = new BinaryReader(File.Open(filepath, FileMode.Open)))
242+
{
243+
var suffix = ReadSuffix(reader);
244+
return new Device.Identification(suffix);
245+
}
246+
}
247+
205248
/// <summary>
206249
/// Extracts the contents of a DFU file.
207250
/// </summary>
208251
/// <param name="filepath">Path to the DFU file</param>
209252
/// <returns>The device and memory image information</returns>
210253
public static FileContent ParseFile(string filepath)
211254
{
212-
FileContent fc;
213-
214255
using (BinaryReader reader = new BinaryReader(File.Open(filepath, FileMode.Open)))
215256
{
216-
// this is the part of the file that the CRC is calculated on
217-
byte[] content = new byte[reader.BaseStream.Length - 4];
218-
reader.Read(content, 0, content.Length);
219-
220-
// read the DFU file suffix first
221-
byte[] suffixdata = new byte[Suffix.Size];
222-
reader.BaseStream.Position = reader.BaseStream.Length - Suffix.Size;
223-
reader.Read(suffixdata, 0, Suffix.Size);
224-
var suffix = suffixdata.ToStruct<Suffix>();
225-
226-
// verify suffix
227-
if (suffix.dwCRC != Crc32.Calculate(content))
228-
{
229-
throw new ArgumentException("The selected dfu file has invalid CRC.");
230-
}
231-
if (suffix.bLength < Suffix.Size)
232-
{
233-
throw new ArgumentException("The selected dfu file has invalid suffix length.");
234-
}
235-
if (suffix.sDfuSignature != Suffix.Signature)
236-
{
237-
throw new ArgumentException("The selected dfu file has invalid suffix signature.");
238-
}
239-
240-
fc = new FileContent(suffix.idVendor, suffix.idProduct, suffix.bcdDevice, suffix.bcdDFU);
257+
var suffix = ReadSuffix(reader);
258+
var devInfo = new Device.Identification(suffix);
259+
var fc = new FileContent(devInfo);
241260

242261
// remove the suffix from the contents
243-
Array.Resize<byte>(ref content, (int)reader.BaseStream.Length - suffix.bLength);
262+
byte[] content = new byte[reader.BaseStream.Length - suffix.bLength];
263+
reader.BaseStream.Position = 0;
264+
reader.Read(content, 0, content.Length);
244265

245266
// if the protocol version is according to USB spec
246267
if (fc.DeviceInfo.DfuVersion <= Protocol.LatestVersion)

0 commit comments

Comments
 (0)