/* ------------------------------------------------------------------------ File: DataExtractionPlugin.cs Module: Vector.ODXStudio.Plugins.DataExtractionPluginExample --------------------------------------------------------------------------- Data Extraction Plugin Example --------------------------------------------------------------------------- Copyright (c) Vector Informatik GmbH. All rights reserved. ------------------------------------------------------------------------ */ using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Text; using Vector.ODXStudio.PluginInterfaces; namespace Vector.ODXStudio.Plugins.DataExtractionPluginExample { public class DataExtractionPlugin : MarshalByRefObject, IDataExtractionPlugin { private const string NAME = "Data Extraction Plugin Example"; private const string DESCRIPTION = "Example plugin that illustrates the usage of the IDataExtractionPlugin interface"; private const string AUTHOR = "Vector Informatik GmbH"; private string mLastError = string.Empty; private List> mDataList; #region MarshalByRefObject overrides /// /// Assure an infinite lifetime for the object /// /// null public override object InitializeLifetimeService() { return null; } #endregion #region Implementation of IPlugin private IDataExtractionPluginHost mHost; public void Initialize(string languageCode) { if (mDataList == null) mDataList = new List>(); } public void Dispose() { mDataList.Clear(); } public string GetLastError() { return mLastError; } public string Name { get { return NAME; } } public string Description { get { return DESCRIPTION; } } public string Author { get { return AUTHOR; } } public string Version { get { Version ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; return string.Format("{0}.{1}.{2}", ver.Major, ver.Minor, ver.Build); } } #endregion #region Implementation of IDataExtractionPlugin public bool ParseFlashData(string flashDataFilePath, string flashQualifier) { mDataList.Clear(); // Extract the data block type from ODXStudio string dataBlockType = string.Empty; if (Host != null && Host.GetNumDataIdentifiers() > 0) { for (int idx = 0; idx < Host.GetNumDataIdentifiers(); ++idx) { switch (Host.GetDataIdentifier(idx)) { case "DATABLOCK-TYPE": dataBlockType = Host.GetDataValue(idx); break; } } } // Copy file string newFileName; if (!CopyFlashFile(out newFileName, flashDataFilePath, dataBlockType)) return false; // Set max segment mDataList.Add(new KeyValuePair("DATABLOCK-SEGMENTS", "00000000;FFFFFFFF")); // Compute a hash on the file and set is as FW-CHECKSUM return ComputeHash(newFileName); } public int GetNumDataIdentifiers() { return mDataList.Count; } public string GetDataIdentifier(int idx) { return idx < mDataList.Count ? mDataList[idx].Key : null; } public string GetDataValue(int idx) { return idx < mDataList.Count ? mDataList[idx].Value : null; } public IDataExtractionPluginHost Host { get { return mHost; } set { mHost = value; } } #endregion /// /// Compute a hash on the file and set is as FW-CHECKSUM /// /// Complete path to file /// True iff successful. False otherwise. private bool ComputeHash(string newFileName) { try { MD5 md5 = MD5.Create(); md5.Initialize(); FileStream fStream; using (fStream = new FileStream(newFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 65536)) { md5.ComputeHash(fStream); StringBuilder builder = new StringBuilder(md5.Hash.Length*2); for (int idx = 0; idx < md5.Hash.Length; ++idx) { builder.Append(Convert.ToUInt16(md5.Hash[idx]).ToString("X")); } mDataList.Add(new KeyValuePair("DATABLOCK-FW-CHECKSUM", builder.ToString())); } } catch (Exception e) { mLastError = string.Format("Failed to compute hash on '{0}'. Message {1}", newFileName, e.Message); return false; } return true; } /// /// Copies the given file by prepending a prefix to it /// Does nothing if the prefix is already present /// /// Complete path to copied file /// Complete path to file to be copied /// Prefix to be added to filename /// True iff successful. False otherwise. private bool CopyFlashFile(out string newDataFilePath, string flashDataFilePath, string prefix) { newDataFilePath = string.Empty; if (string.IsNullOrEmpty(flashDataFilePath)) { mLastError = string.Format("Empty flashDataFilePath received."); return false; } if (!File.Exists(flashDataFilePath)) { mLastError = string.Format("File '{0}' does not exist.", flashDataFilePath); return false; } newDataFilePath = flashDataFilePath; string filename = Path.GetFileName(flashDataFilePath); if (string.IsNullOrEmpty(filename)) { mLastError = string.Format("Could not retrieve filename from '{0}'.", flashDataFilePath); return false; } string dir = Path.GetDirectoryName(flashDataFilePath); if (string.IsNullOrEmpty(dir)) { mLastError = string.Format("Could not retrieve directory from '{0}'.", flashDataFilePath); return false; } // Copy file only if it does not start with the given prefix already if (!string.IsNullOrEmpty(prefix) && !filename.StartsWith(prefix)) { newDataFilePath = Path.Combine(dir, string.Format("{0}_{1}", prefix, filename)); try { File.Copy(flashDataFilePath, newDataFilePath, true); } catch (Exception) { mLastError = string.Format("Could not copy flash file from '{0}' to '{1}'.", flashDataFilePath, newDataFilePath); return false; } } // Set new flash data file name in ODXStudio mDataList.Add(new KeyValuePair("FLASHDATA-DATAFILE", newDataFilePath)); return true; } } }