source:
branches/crossvalidation-2434/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/HeuristicLab.EPPlus-4.0.3/epplus-4.0.3-Mono.patch
@
15166
Last change on this file since 15166 was 12715, checked in by mkommend, 9 years ago | |
---|---|
File size: 92.1 KB |
-
ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs
1 /*******************************************************************************2 * You may amend and distribute as you like, but don't remove this header!3 *4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.5 * See http://www.codeplex.com/EPPlus for details.6 *7 * Copyright (C) 2011 Jan KÀllman8 *9 * This library is free software; you can redistribute it and/or10 * modify it under the terms of the GNU Lesser General Public11 * License as published by the Free Software Foundation; either12 * version 2.1 of the License, or (at your option) any later version.13 14 * This library is distributed in the hope that it will be useful,15 * but WITHOUT ANY WARRANTY; without even the implied warranty of16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.17 * See the GNU Lesser General Public License for more details.18 *19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html21 *22 * All code and executables are provided "as is" with no warranty either express or implied.23 * The author accepts no liability for any damage or loss of business that this product may cause.24 *25 * Code change notes:26 *27 * Author Change Date28 * ******************************************************************************29 * Eyal Seagull Added 2012-04-0330 *******************************************************************************/31 using System;32 using System.Collections.Generic;33 using System.Linq;34 using System.Text;35 using System.Drawing;36 using System.Xml;37 using OfficeOpenXml.Utils;38 using System.Text.RegularExpressions;39 using System.Globalization;40 using System.Security;41 42 namespace OfficeOpenXml.ConditionalFormatting43 {44 /// <summary>45 /// 18.3.1.11 cfvo (Conditional Format Value Object)46 /// Describes the values of the interpolation points in a gradient scale.47 /// </summary>48 public class ExcelConditionalFormattingIconDataBarValue49 : XmlHelper50 {51 /****************************************************************************************/52 53 #region Private Properties54 private eExcelConditionalFormattingRuleType _ruleType;55 private ExcelWorksheet _worksheet;56 #endregion Private Properties57 58 /****************************************************************************************/59 60 #region Constructors61 /// <summary>62 /// Initialize the cfvo (§18.3.1.11) node63 /// </summary>64 /// <param name="type"></param>65 /// <param name="value"></param>66 /// <param name="formula"></param>67 /// <param name="ruleType"></param>68 /// <param name="address"></param>69 /// <param name="priority"></param>70 /// <param name="worksheet"></param>71 /// <param name="itemElementNode">The cfvo (§18.3.1.11) node parent. Can be any of the following:72 /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49)</param>73 /// <param name="namespaceManager"></param>74 internal ExcelConditionalFormattingIconDataBarValue(75 eExcelConditionalFormattingValueObjectType type,76 double value,77 string formula,78 eExcelConditionalFormattingRuleType ruleType,79 ExcelAddress address,80 int priority,81 ExcelWorksheet worksheet,82 XmlNode itemElementNode,83 XmlNamespaceManager namespaceManager)84 : this(85 ruleType,86 address,87 worksheet,88 itemElementNode,89 namespaceManager)90 {91 Require.Argument(priority).IsInRange(1, int.MaxValue, "priority");92 93 // Check if the parent does not exists94 if (itemElementNode == null)95 {96 // Get the parent node path by the rule type97 string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType(98 ruleType);99 100 // Check for en error (rule type does not have <cfvo>)101 if (parentNodePath == string.Empty)102 {103 throw new Exception(104 ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);105 }106 107 // Point to the <cfvo> parent node108 itemElementNode = _worksheet.WorksheetXml.SelectSingleNode(109 string.Format(110 "//{0}[{1}='{2}']/{3}[{4}='{5}']/{6}",111 // {0}112 ExcelConditionalFormattingConstants.Paths.ConditionalFormatting,113 // {1}114 ExcelConditionalFormattingConstants.Paths.SqrefAttribute,115 // {2}116 address.Address,117 // {3}118 ExcelConditionalFormattingConstants.Paths.CfRule,119 // {4}120 ExcelConditionalFormattingConstants.Paths.PriorityAttribute,121 // {5}122 priority,123 // {6}124 parentNodePath),125 _worksheet.NameSpaceManager);126 127 // Check for en error (rule type does not have <cfvo>)128 if (itemElementNode == null)129 {130 throw new Exception(131 ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);132 }133 }134 135 TopNode = itemElementNode;136 137 // Save the attributes138 RuleType = ruleType;139 Type = type;140 Value = value;141 Formula = formula;142 }143 /// <summary>144 /// Initialize the cfvo (§18.3.1.11) node145 /// </summary>146 /// <param name="ruleType"></param>147 /// <param name="address"></param>148 /// <param name="worksheet"></param>149 /// <param name="itemElementNode">The cfvo (§18.3.1.11) node parent. Can be any of the following:150 /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49)</param>151 /// <param name="namespaceManager"></param>152 internal ExcelConditionalFormattingIconDataBarValue(153 eExcelConditionalFormattingRuleType ruleType,154 ExcelAddress address,155 ExcelWorksheet worksheet,156 XmlNode itemElementNode,157 XmlNamespaceManager namespaceManager)158 : base(159 namespaceManager,160 itemElementNode)161 {162 Require.Argument(address).IsNotNull("address");163 Require.Argument(worksheet).IsNotNull("worksheet");164 165 // Save the worksheet for private methods to use166 _worksheet = worksheet;167 168 // Schema order list169 SchemaNodeOrder = new string[]170 {171 ExcelConditionalFormattingConstants.Nodes.Cfvo,172 };173 174 //Check if the parent does not exists175 if (itemElementNode == null)176 {177 // Get the parent node path by the rule type178 string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType(179 ruleType);180 181 // Check for en error (rule type does not have <cfvo>)182 if (parentNodePath == string.Empty)183 {184 throw new Exception(185 ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);186 }187 }188 RuleType = ruleType;189 }190 /// <summary>191 /// Initialize the <see cref="ExcelConditionalFormattingColorScaleValue"/>192 /// </summary>193 /// <param name="type"></param>194 /// <param name="value"></param>195 /// <param name="formula"></param>196 /// <param name="ruleType"></param>197 /// <param name="priority"></param>198 /// <param name="address"></param>199 /// <param name="worksheet"></param>200 /// <param name="namespaceManager"></param>201 internal ExcelConditionalFormattingIconDataBarValue(202 eExcelConditionalFormattingValueObjectType type,203 double value,204 string formula,205 eExcelConditionalFormattingRuleType ruleType,206 ExcelAddress address,207 int priority,208 ExcelWorksheet worksheet,209 XmlNamespaceManager namespaceManager)210 : this(211 type,212 value,213 formula,214 ruleType,215 address,216 priority,217 worksheet,218 null,219 namespaceManager)220 {221 222 }223 /// <summary>224 /// Initialize the <see cref="ExcelConditionalFormattingColorScaleValue"/>225 /// </summary>226 /// <param name="type"></param>227 /// <param name="color"></param>228 /// <param name="ruleType"></param>229 /// <param name="priority"></param>230 /// <param name="address"></param>231 /// <param name="worksheet"></param>232 /// <param name="namespaceManager"></param>233 internal ExcelConditionalFormattingIconDataBarValue(234 eExcelConditionalFormattingValueObjectType type,235 Color color,236 eExcelConditionalFormattingRuleType ruleType,237 ExcelAddress address,238 int priority,239 ExcelWorksheet worksheet,240 XmlNamespaceManager namespaceManager)241 : this(242 type,243 0,244 null,245 ruleType,246 address,247 priority,248 worksheet,249 null,250 namespaceManager)251 {252 }253 #endregion Constructors254 255 /****************************************************************************************/256 257 #region Methods258 #endregion259 260 /****************************************************************************************/261 262 #region Exposed Properties263 264 /// <summary>265 ///266 /// </summary>267 internal eExcelConditionalFormattingRuleType RuleType268 {269 get { return _ruleType; }270 set { _ruleType = value; }271 }272 273 /// <summary>274 ///275 /// </summary>276 public eExcelConditionalFormattingValueObjectType Type277 {278 get279 {280 var typeAttribute = GetXmlNodeString(ExcelConditionalFormattingConstants.Paths.TypeAttribute);281 282 return ExcelConditionalFormattingValueObjectType.GetTypeByAttrbiute(typeAttribute);283 }284 set285 {286 if ((_ruleType==eExcelConditionalFormattingRuleType.ThreeIconSet || _ruleType==eExcelConditionalFormattingRuleType.FourIconSet || _ruleType==eExcelConditionalFormattingRuleType.FiveIconSet) &&287 (value == eExcelConditionalFormattingValueObjectType.Min || value == eExcelConditionalFormattingValueObjectType.Max))288 {289 throw(new ArgumentException("Value type can't be Min or Max for icon sets"));290 }291 SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.TypeAttribute, value.ToString().ToLower(CultureInfo.InvariantCulture));292 }293 }294 295 /// <summary>296 /// Get/Set the 'cfvo' node @val attribute297 /// </summary>298 public Double Value299 {300 get301 {302 if ((Type == eExcelConditionalFormattingValueObjectType.Num)303 || (Type == eExcelConditionalFormattingValueObjectType.Percent)304 || (Type == eExcelConditionalFormattingValueObjectType.Percentile))305 {306 return GetXmlNodeDouble(ExcelConditionalFormattingConstants.Paths.ValAttribute);307 }308 else309 {310 return 0;311 }312 }313 set314 {315 string valueToStore = string.Empty;316 317 // Only some types use the @val attribute318 if ((Type == eExcelConditionalFormattingValueObjectType.Num)319 || (Type == eExcelConditionalFormattingValueObjectType.Percent)320 || (Type == eExcelConditionalFormattingValueObjectType.Percentile))321 {322 valueToStore = value.ToString(CultureInfo.InvariantCulture);323 }324 325 SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute, valueToStore);326 }327 }328 329 /// <summary>330 /// Get/Set the Formula of the Object Value (uses the same attribute as the Value)331 /// </summary>332 public string Formula333 {334 get335 {336 // Return empty if the Object Value type is not Formula337 if (Type != eExcelConditionalFormattingValueObjectType.Formula)338 {339 return string.Empty;340 }341 342 // Excel stores the formula in the @val attribute343 return GetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute);344 }345 set346 {347 // Only store the formula if the Object Value type is Formula348 if (Type == eExcelConditionalFormattingValueObjectType.Formula)349 {350 SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute, value);351 }352 }353 }354 #endregion Exposed Properties355 356 /****************************************************************************************/357 }358 }359 No newline at end of file -
ExcelWorkbook.cs
336 336 if (_standardFontWidth == decimal.MinValue || _fontID != Styles.Fonts[0].Id) 337 337 { 338 338 var font = Styles.Fonts[0]; 339 #if __MonoCS__ 340 _standardFontWidth = (int)(font.Size * (2D / 3D)); //Aprox for Calibri. 341 #else 339 342 try 340 343 { 341 344 //Font f = new Font(font.Name, font.Size); … … 373 376 { 374 377 _standardFontWidth = (int)(font.Size * (2D / 3D)); //Aprox for Calibri. 375 378 } 379 #endif 376 380 } 377 381 return _standardFontWidth; 378 382 } -
VBA/ExcelVBAModuleCollection.cs
1 /*******************************************************************************2 * You may amend and distribute as you like, but don't remove this header!3 *4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.5 * See http://www.codeplex.com/EPPlus for details.6 *7 * Copyright (C) 2011 Jan KÀllman8 *9 * This library is free software; you can redistribute it and/or10 * modify it under the terms of the GNU Lesser General Public11 * License as published by the Free Software Foundation; either12 * version 2.1 of the License, or (at your option) any later version.13 14 * This library is distributed in the hope that it will be useful,15 * but WITHOUT ANY WARRANTY; without even the implied warranty of16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.17 * See the GNU Lesser General Public License for more details.18 *19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html21 *22 * All code and executables are provided "as is" with no warranty either express or implied.23 * The author accepts no liability for any damage or loss of business that this product may cause.24 *25 * Code change notes:26 *27 * Author Change Date28 *******************************************************************************29 * Jan KÀllman Added 12-APR-201230 *******************************************************************************/31 using System;32 using System.Collections.Generic;33 using System.Linq;34 using System.Text;35 36 namespace OfficeOpenXml.VBA37 {38 /// <summary>39 /// Base class for VBA collections40 /// </summary>41 /// <typeparam name="T"></typeparam>42 public class ExcelVBACollectionBase<T> : IEnumerable<T>43 {44 internal protected List<T> _list=new List<T>();45 public IEnumerator<T> GetEnumerator()46 {47 return _list.GetEnumerator();48 }49 50 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()51 {52 return _list.GetEnumerator();53 }54 /// <summary>55 /// Indexer56 /// </summary>57 /// <param name="Name">Name</param>58 /// <returns></returns>59 public T this [string Name]60 {61 get62 {63 return _list.Find((f) => f.GetType().GetProperty("Name").GetValue(f, null).ToString().Equals(Name,StringComparison.InvariantCultureIgnoreCase));64 }65 }66 /// <summary>67 /// Indexer68 /// </summary>69 /// <param name="Index">Position</param>70 /// <returns></returns>71 public T this[int Index]72 {73 get74 {75 return _list[Index];76 }77 }78 /// <summary>79 /// Number of items in the collection80 /// </summary>81 public int Count82 {83 get { return _list.Count; }84 }85 /// <summary>86 /// If a specific name exists in the collection87 /// </summary>88 /// <param name="Name">The name</param>89 /// <returns>True if the name exists</returns>90 public bool Exists(string Name)91 {92 return _list.Exists((f) => f.GetType().GetProperty("Name").GetValue(f, null).ToString().Equals(Name,StringComparison.InvariantCultureIgnoreCase));93 }94 /// <summary>95 /// Removes the item96 /// </summary>97 /// <param name="Item"></param>98 public void Remove(T Item)99 {100 _list.Remove(Item);101 }102 /// <summary>103 /// Removes the item at the specified index104 /// </summary>105 /// <param name="index">THe index</param>106 public void RemoveAt(int index)107 {108 _list.RemoveAt(index);109 }110 111 internal void Clear()112 {113 _list.Clear();114 }115 }116 /// <summary>117 /// Collection class for VBA modules118 /// </summary>119 public class ExcelVbaModuleCollection : ExcelVBACollectionBase<ExcelVBAModule>120 {121 ExcelVbaProject _project;122 internal ExcelVbaModuleCollection (ExcelVbaProject project)123 {124 _project=project;125 }126 internal void Add(ExcelVBAModule Item)127 {128 _list.Add(Item);129 }130 /// <summary>131 /// Adds a new VBA Module132 /// </summary>133 /// <param name="Name">The name of the module</param>134 /// <returns>The module object</returns>135 public ExcelVBAModule AddModule(string Name)136 {137 if (this[Name] != null)138 {139 throw(new ArgumentException("Vba modulename already exist."));140 }141 var m = new ExcelVBAModule();142 m.Name = Name;143 m.Type = eModuleType.Module;144 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = Name, DataType = eAttributeDataType.String });145 m.Type = eModuleType.Module;146 _list.Add(m);147 return m;148 }149 /// <summary>150 /// Adds a new VBA class151 /// </summary>152 /// <param name="Name">The name of the class</param>153 /// <param name="Exposed">Private or Public not createble</param>154 /// <returns>The class object</returns>155 public ExcelVBAModule AddClass(string Name, bool Exposed)156 {157 var m = new ExcelVBAModule();158 m.Name = Name;159 m.Type = eModuleType.Class;160 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = Name, DataType = eAttributeDataType.String });161 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}", DataType = eAttributeDataType.String });162 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString });163 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString });164 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "False", DataType = eAttributeDataType.NonString });165 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = Exposed ? "True" : "False", DataType = eAttributeDataType.NonString });166 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString });167 m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "False", DataType = eAttributeDataType.NonString });168 169 //m.Code = _project.GetBlankClassModule(Name, Exposed);170 m.Private = !Exposed;171 //m.ClassID=172 _list.Add(m);173 return m;174 }175 }176 /// <summary>177 /// A collection of the vba projects references178 /// </summary>179 public class ExcelVbaReferenceCollection : ExcelVBACollectionBase<ExcelVbaReference>180 {181 internal ExcelVbaReferenceCollection()182 {183 184 }185 /// <summary>186 /// Adds a new reference187 /// </summary>188 /// <param name="Item">The reference object</param>189 public void Add(ExcelVbaReference Item)190 {191 _list.Add(Item);192 }193 }194 /// <summary>195 /// A collection of the module level attributes196 /// </summary>197 public class ExcelVbaModuleAttributesCollection : ExcelVBACollectionBase<ExcelVbaModuleAttribute>198 {199 internal string GetAttributeText()200 {201 StringBuilder sb=new StringBuilder();202 203 foreach (var attr in this)204 {205 sb.AppendFormat("Attribute {0} = {1}\r\n", attr.Name, attr.DataType==eAttributeDataType.String ? "\"" + attr.Value + "\"" : attr.Value);206 }207 return sb.ToString();208 }209 }210 } -
VBA/ExcelVBAProject.cs
1 /*******************************************************************************2 * You may amend and distribute as you like, but don't remove this header!3 *4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.5 * See http://www.codeplex.com/EPPlus for details.6 *7 * Copyright (C) 2011 Jan KÀllman8 *9 * All code and executables are provided "as is" with no warranty either express or implied.10 * The author accepts no liability for any damage or loss of business that this product may cause.11 *12 * If you want to understand this code have a look at the Office VBA File Format Structure Specification (MS-OVBA.PDF) or13 * http://msdn.microsoft.com/en-us/library/cc313094(v=office.12).aspx14 *15 * * Code change notes:16 *17 * Author Change Date18 *******************************************************************************19 * Jan KÀllman Added 26-MAR-201220 *******************************************************************************/21 using System;22 using System.Collections.Generic;23 using System.Globalization;24 using System.Linq;25 using System.Text;26 using System.IO;27 using OfficeOpenXml.Utils;28 using System.Security.Cryptography.Pkcs;29 using System.Security.Cryptography.X509Certificates;30 using System.Security.Cryptography;31 using System.Text.RegularExpressions;32 33 namespace OfficeOpenXml.VBA34 {35 /// <summary>36 /// Represents the VBA project part of the package37 /// </summary>38 public class ExcelVbaProject39 {40 const string schemaRelVba = "http://schemas.microsoft.com/office/2006/relationships/vbaProject";41 internal const string PartUri = @"/xl/vbaProject.bin";42 #region Classes & Enums43 /// <summary>44 /// Type of system where the VBA project was created.45 /// </summary>46 public enum eSyskind47 {48 Win16 = 0,49 Win32 = 1,50 Macintosh = 2,51 Win64 = 352 }53 54 #endregion55 internal ExcelVbaProject(ExcelWorkbook wb)56 {57 _wb = wb;58 _pck = _wb._package.Package;59 References = new ExcelVbaReferenceCollection();60 Modules = new ExcelVbaModuleCollection(this);61 var rel = _wb.Part.GetRelationshipsByType(schemaRelVba).FirstOrDefault();62 if (rel != null)63 {64 Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);65 Part = _pck.GetPart(Uri);66 #if !MONO67 GetProject();68 #endif69 }70 else71 {72 Lcid = 0;73 Part = null;74 }75 }76 internal ExcelWorkbook _wb;77 internal Packaging.ZipPackage _pck;78 #region Dir Stream Properties79 /// <summary>80 /// System kind. Default Win32.81 /// </summary>82 public eSyskind SystemKind { get; set; }83 /// <summary>84 /// Name of the project85 /// </summary>86 public string Name { get; set; }87 /// <summary>88 /// A description of the project89 /// </summary>90 public string Description { get; set; }91 /// <summary>92 /// A helpfile93 /// </summary>94 public string HelpFile1 { get; set; }95 /// <summary>96 /// Secondary helpfile97 /// </summary>98 public string HelpFile2 { get; set; }99 /// <summary>100 /// Context if refering the helpfile101 /// </summary>102 public int HelpContextID { get; set; }103 /// <summary>104 /// Conditional compilation constants105 /// </summary>106 public string Constants { get; set; }107 /// <summary>108 /// Codepage for encoding. Default is current regional setting.109 /// </summary>110 public int CodePage { get; internal set; }111 internal int LibFlags { get; set; }112 internal int MajorVersion { get; set; }113 internal int MinorVersion { get; set; }114 internal int Lcid { get; set; }115 internal int LcidInvoke { get; set; }116 internal string ProjectID { get; set; }117 internal string ProjectStreamText { get; set; }118 /// <summary>119 /// Project references120 /// </summary>121 public ExcelVbaReferenceCollection References { get; set; }122 /// <summary>123 /// Code Modules (Modules, classes, designer code)124 /// </summary>125 public ExcelVbaModuleCollection Modules { get; set; }126 ExcelVbaSignature _signature = null;127 /// <summary>128 /// The digital signature129 /// </summary>130 public ExcelVbaSignature Signature131 {132 get133 {134 if (_signature == null)135 {136 _signature=new ExcelVbaSignature(Part);137 }138 return _signature;139 }140 }141 ExcelVbaProtection _protection=null;142 /// <summary>143 /// VBA protection144 /// </summary>145 public ExcelVbaProtection Protection146 {147 get148 {149 if (_protection == null)150 {151 _protection = new ExcelVbaProtection(this);152 }153 return _protection;154 }155 }156 #endregion157 #if !MONO158 #region Read Project159 private void GetProject()160 {161 162 var stream = Part.GetStream();163 byte[] vba;164 vba = new byte[stream.Length];165 stream.Read(vba, 0, (int)stream.Length);166 Document = new CompoundDocument(vba);167 168 ReadDirStream();169 ProjectStreamText = Encoding.GetEncoding(CodePage).GetString(Document.Storage.DataStreams["PROJECT"]);170 ReadModules();171 ReadProjectProperties();172 }173 private void ReadModules()174 {175 foreach (var modul in Modules)176 {177 var stream = Document.Storage.SubStorage["VBA"].DataStreams[modul.streamName];178 var byCode = CompoundDocument.DecompressPart(stream, (int)modul.ModuleOffset);179 string code = Encoding.GetEncoding(CodePage).GetString(byCode);180 int pos=0;181 while(pos+9<code.Length && code.Substring(pos,9)=="Attribute")182 {183 int linePos=code.IndexOf("\r\n",pos);184 string[] lineSplit;185 if(linePos>0)186 {187 lineSplit = code.Substring(pos + 9, linePos - pos - 9).Split('=');188 }189 else190 {191 lineSplit=code.Substring(pos+9).Split(new char[]{'='},1);192 }193 if (lineSplit.Length > 1)194 {195 lineSplit[1] = lineSplit[1].Trim();196 var attr =197 new ExcelVbaModuleAttribute()198 {199 Name = lineSplit[0].Trim(),200 DataType = lineSplit[1].StartsWith("\"") ? eAttributeDataType.String : eAttributeDataType.NonString,201 Value = lineSplit[1].StartsWith("\"") ? lineSplit[1].Substring(1, lineSplit[1].Length - 2) : lineSplit[1]202 };203 modul.Attributes._list.Add(attr);204 }205 pos = linePos + 2;206 }207 modul.Code=code.Substring(pos);208 }209 }210 211 private void ReadProjectProperties()212 {213 _protection = new ExcelVbaProtection(this);214 string prevPackage = "";215 var lines = Regex.Split(ProjectStreamText, "\r\n");216 foreach (string line in lines)217 {218 if (line.StartsWith("["))219 {220 221 }222 else223 {224 var split = line.Split('=');225 if (split.Length > 1 && split[1].Length > 1 && split[1].StartsWith("\"")) //Remove any double qouates226 {227 split[1] = split[1].Substring(1, split[1].Length - 2);228 }229 switch (split[0])230 {231 case "ID":232 ProjectID = split[1];233 break;234 case "Document":235 string mn = split[1].Substring(0, split[1].IndexOf("/&H"));236 Modules[mn].Type = eModuleType.Document;237 break;238 case "Package":239 prevPackage = split[1];240 break;241 case "BaseClass":242 Modules[split[1]].Type = eModuleType.Designer;243 Modules[split[1]].ClassID = prevPackage;244 break;245 case "Module":246 Modules[split[1]].Type = eModuleType.Module;247 break;248 case "Class":249 Modules[split[1]].Type = eModuleType.Class;250 break;251 case "HelpFile":252 case "Name":253 case "HelpContextID":254 case "Description":255 case "VersionCompatible32":256 break;257 //393222000"258 case "CMG":259 byte[] cmg = Decrypt(split[1]);260 _protection.UserProtected = (cmg[0] & 1) != 0;261 _protection.HostProtected = (cmg[0] & 2) != 0;262 _protection.VbeProtected = (cmg[0] & 4) != 0;263 break;264 case "DPB":265 byte[] dpb = Decrypt(split[1]);266 if (dpb.Length >= 28)267 {268 byte reserved = dpb[0];269 var flags = new byte[3];270 Array.Copy(dpb, 1, flags, 0, 3);271 var keyNoNulls = new byte[4];272 _protection.PasswordKey = new byte[4];273 Array.Copy(dpb, 4, keyNoNulls, 0, 4);274 var hashNoNulls = new byte[20];275 _protection.PasswordHash = new byte[20];276 Array.Copy(dpb, 8, hashNoNulls, 0, 20);277 //Handle 0x00 bitwise 2.4.4.3278 for (int i = 0; i < 24; i++)279 {280 int bit = 128 >> (int)((i % 8));281 if (i < 4)282 {283 if ((int)(flags[0] & bit) == 0)284 {285 _protection.PasswordKey[i] = 0;286 }287 else288 {289 _protection.PasswordKey[i] = keyNoNulls[i];290 }291 }292 else293 {294 int flagIndex = (i - i % 8) / 8;295 if ((int)(flags[flagIndex] & bit) == 0)296 {297 _protection.PasswordHash[i - 4] = 0;298 }299 else300 {301 _protection.PasswordHash[i - 4] = hashNoNulls[i - 4];302 }303 }304 }305 }306 break;307 case "GC":308 _protection.VisibilityState = Decrypt(split[1])[0] == 0xFF;309 310 break;311 }312 }313 }314 }315 316 /// <summary>317 /// 2.4.3.3 Decryption318 /// </summary>319 /// <param name="value">Byte hex string</param>320 /// <returns>The decrypted value</returns>321 private byte[] Decrypt(string value)322 {323 byte[] enc = GetByte(value);324 byte[] dec = new byte[(value.Length - 1)];325 byte seed, version, projKey, ignoredLength;326 seed = enc[0];327 dec[0] = (byte)(enc[1] ^ seed);328 dec[1] = (byte)(enc[2] ^ seed);329 for (int i = 2; i < enc.Length - 1; i++)330 {331 dec[i] = (byte)(enc[i + 1] ^ (enc[i - 1] + dec[i - 1]));332 }333 version = dec[0];334 projKey = dec[1];335 ignoredLength = (byte)((seed & 6) / 2);336 int datalength = BitConverter.ToInt32(dec, ignoredLength + 2);337 var data = new byte[datalength];338 Array.Copy(dec, 6 + ignoredLength, data, 0, datalength);339 return data;340 }341 /// <summary>342 /// 2.4.3.2 Encryption343 /// </summary>344 /// <param name="value"></param>345 /// <returns>Byte hex string</returns>346 private string Encrypt(byte[] value)347 {348 byte[] seed = new byte[1];349 var rn = RandomNumberGenerator.Create();350 rn.GetBytes(seed);351 BinaryWriter br = new BinaryWriter(new MemoryStream());352 byte[] enc = new byte[value.Length + 10];353 enc[0] = seed[0];354 enc[1] = (byte)(2 ^ seed[0]);355 356 byte projKey = 0;357 358 foreach (var c in ProjectID)359 {360 projKey += (byte)c;361 }362 enc[2] = (byte)(projKey ^ seed[0]);363 var ignoredLength = (seed[0] & 6) / 2;364 for (int i = 0; i < ignoredLength; i++)365 {366 br.Write(seed[0]);367 }368 br.Write(value.Length);369 br.Write(value);370 371 int pos = 3;372 byte pb = projKey;373 foreach (var b in ((MemoryStream)br.BaseStream).ToArray())374 {375 enc[pos] = (byte)(b ^ (enc[pos - 2] + pb));376 pos++;377 pb = b;378 }379 380 return GetString(enc, pos - 1);381 }382 private string GetString(byte[] value, int max)383 {384 string ret = "";385 for (int i = 0; i <= max; i++)386 {387 if (value[i] < 16)388 {389 ret += "0" + value[i].ToString("x");390 }391 else392 {393 ret += value[i].ToString("x");394 }395 }396 return ret.ToUpper(CultureInfo.InvariantCulture);397 }398 private byte[] GetByte(string value)399 {400 byte[] ret = new byte[value.Length / 2];401 for (int i = 0; i < ret.Length; i++)402 {403 ret[i] = byte.Parse(value.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier);404 }405 return ret;406 }407 private void ReadDirStream()408 {409 byte[] dir = CompoundDocument.DecompressPart(Document.Storage.SubStorage["VBA"].DataStreams["dir"]);410 MemoryStream ms = new MemoryStream(dir);411 BinaryReader br = new BinaryReader(ms);412 ExcelVbaReference currentRef = null;413 string referenceName = "";414 ExcelVBAModule currentModule = null;415 bool terminate = false;416 while (br.BaseStream.Position < br.BaseStream.Length && terminate == false)417 {418 ushort id = br.ReadUInt16();419 uint size = br.ReadUInt32();420 switch (id)421 {422 case 0x01:423 SystemKind = (eSyskind)br.ReadUInt32();424 break;425 case 0x02:426 Lcid = (int)br.ReadUInt32();427 break;428 case 0x03:429 CodePage = (int)br.ReadUInt16();430 break;431 case 0x04:432 Name = GetString(br, size);433 break;434 case 0x05:435 Description = GetUnicodeString(br, size);436 break;437 case 0x06:438 HelpFile1 = GetString(br, size);439 break;440 case 0x3D:441 HelpFile2 = GetString(br, size);442 break;443 case 0x07:444 HelpContextID = (int)br.ReadUInt32();445 break;446 case 0x08:447 LibFlags = (int)br.ReadUInt32();448 break;449 case 0x09:450 MajorVersion = (int)br.ReadUInt32();451 MinorVersion = (int)br.ReadUInt16();452 break;453 case 0x0C:454 Constants = GetUnicodeString(br, size);455 break;456 case 0x0D:457 uint sizeLibID = br.ReadUInt32();458 var regRef = new ExcelVbaReference();459 regRef.Name = referenceName;460 regRef.ReferenceRecordID = id;461 regRef.Libid = GetString(br, sizeLibID);462 uint reserved1 = br.ReadUInt32();463 ushort reserved2 = br.ReadUInt16();464 References.Add(regRef);465 break;466 case 0x0E:467 var projRef = new ExcelVbaReferenceProject();468 projRef.ReferenceRecordID = id;469 projRef.Name = referenceName;470 sizeLibID = br.ReadUInt32();471 projRef.Libid = GetString(br, sizeLibID);472 sizeLibID = br.ReadUInt32();473 projRef.LibIdRelative = GetString(br, sizeLibID);474 projRef.MajorVersion = br.ReadUInt32();475 projRef.MinorVersion = br.ReadUInt16();476 References.Add(projRef);477 break;478 case 0x0F:479 ushort modualCount = br.ReadUInt16();480 break;481 case 0x13:482 ushort cookie = br.ReadUInt16();483 break;484 case 0x14:485 LcidInvoke = (int)br.ReadUInt32();486 break;487 case 0x16:488 referenceName = GetUnicodeString(br, size);489 break;490 case 0x19:491 currentModule = new ExcelVBAModule();492 currentModule.Name = GetUnicodeString(br, size);493 Modules.Add(currentModule);494 break;495 case 0x1A:496 currentModule.streamName = GetUnicodeString(br, size);497 break;498 case 0x1C:499 currentModule.Description = GetUnicodeString(br, size);500 break;501 case 0x1E:502 currentModule.HelpContext = (int)br.ReadUInt32();503 break;504 case 0x21:505 case 0x22:506 break;507 case 0x2B: //Modul Terminator508 break;509 case 0x2C:510 currentModule.Cookie = br.ReadUInt16();511 break;512 case 0x31:513 currentModule.ModuleOffset = br.ReadUInt32();514 break;515 case 0x10:516 terminate = true;517 break;518 case 0x30:519 var extRef = (ExcelVbaReferenceControl)currentRef;520 var sizeExt = br.ReadUInt32();521 extRef.LibIdExternal = GetString(br, sizeExt);522 523 uint reserved4 = br.ReadUInt32();524 ushort reserved5 = br.ReadUInt16();525 extRef.OriginalTypeLib = new Guid(br.ReadBytes(16));526 extRef.Cookie = br.ReadUInt32();527 break;528 case 0x33:529 currentRef = new ExcelVbaReferenceControl();530 currentRef.ReferenceRecordID = id;531 currentRef.Name = referenceName;532 currentRef.Libid = GetString(br, size);533 References.Add(currentRef);534 break;535 case 0x2F:536 var contrRef = (ExcelVbaReferenceControl)currentRef;537 contrRef.ReferenceRecordID = id;538 539 var sizeTwiddled = br.ReadUInt32();540 contrRef.LibIdTwiddled = GetString(br, sizeTwiddled);541 var r1 = br.ReadUInt32();542 var r2 = br.ReadUInt16();543 544 break;545 case 0x25:546 currentModule.ReadOnly = true;547 break;548 case 0x28:549 currentModule.Private = true;550 break;551 default:552 break;553 }554 }555 }556 #endregion557 558 #region Save Project559 internal void Save()560 {561 if (Validate())562 {563 CompoundDocument doc = new CompoundDocument();564 doc.Storage = new CompoundDocument.StoragePart();565 var store = new CompoundDocument.StoragePart();566 doc.Storage.SubStorage.Add("VBA", store);567 568 store.DataStreams.Add("_VBA_PROJECT", CreateVBAProjectStream());569 store.DataStreams.Add("dir", CreateDirStream());570 foreach (var module in Modules)571 {572 store.DataStreams.Add(module.Name, CompoundDocument.CompressPart(Encoding.GetEncoding(CodePage).GetBytes(module.Attributes.GetAttributeText() + module.Code)));573 }574 575 //Copy streams from the template, if used.576 if (Document != null)577 {578 foreach (var ss in Document.Storage.SubStorage)579 {580 if (ss.Key != "VBA")581 {582 doc.Storage.SubStorage.Add(ss.Key, ss.Value);583 }584 }585 foreach (var s in Document.Storage.DataStreams)586 {587 if (s.Key != "dir" && s.Key != "PROJECT" && s.Key != "PROJECTwm")588 {589 doc.Storage.DataStreams.Add(s.Key, s.Value);590 }591 }592 }593 594 doc.Storage.DataStreams.Add("PROJECT", CreateProjectStream());595 doc.Storage.DataStreams.Add("PROJECTwm", CreateProjectwmStream());596 597 if (Part == null)598 {599 Uri = new Uri(PartUri, UriKind.Relative);600 Part = _pck.CreatePart(Uri, ExcelPackage.schemaVBA);601 var rel = _wb.Part.CreateRelationship(Uri, Packaging.TargetMode.Internal, schemaRelVba);602 }603 var vbaBuffer=doc.Save();604 var st = Part.GetStream(FileMode.Create);605 st.Write(vbaBuffer, 0, vbaBuffer.Length);606 st.Flush();607 //Save the digital signture608 Signature.Save(this);609 }610 }611 612 private bool Validate()613 {614 Description = Description ?? "";615 HelpFile1 = HelpFile1 ?? "";616 HelpFile2 = HelpFile2 ?? "";617 Constants = Constants ?? "";618 return true;619 }620 621 /// <summary>622 /// MS-OVBA 2.3.4.1623 /// </summary>624 /// <returns></returns>625 private byte[] CreateVBAProjectStream()626 {627 BinaryWriter bw = new BinaryWriter(new MemoryStream());628 bw.Write((ushort)0x61CC); //Reserved1629 bw.Write((ushort)0xFFFF); //Version630 bw.Write((byte)0x0); //Reserved3631 bw.Write((ushort)0x0); //Reserved4632 return ((MemoryStream)bw.BaseStream).ToArray();633 }634 /// <summary>635 /// MS-OVBA 2.3.4.1636 /// </summary>637 /// <returns></returns>638 private byte[] CreateDirStream()639 {640 BinaryWriter bw = new BinaryWriter(new MemoryStream());641 642 /****** PROJECTINFORMATION Record ******/643 bw.Write((ushort)1); //ID644 bw.Write((uint)4); //Size645 bw.Write((uint)SystemKind); //SysKind646 647 bw.Write((ushort)2); //ID648 bw.Write((uint)4); //Size649 bw.Write((uint)Lcid); //Lcid650 651 bw.Write((ushort)0x14); //ID652 bw.Write((uint)4); //Size653 bw.Write((uint)LcidInvoke); //Lcid Invoke654 655 bw.Write((ushort)3); //ID656 bw.Write((uint)2); //Size657 bw.Write((ushort)CodePage); //Codepage658 659 //ProjectName660 bw.Write((ushort)4); //ID661 bw.Write((uint)Name.Length); //Size662 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Name)); //Project Name663 664 //Description665 bw.Write((ushort)5); //ID666 bw.Write((uint)Description.Length); //Size667 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Description)); //Project Name668 bw.Write((ushort)0x40); //ID669 bw.Write((uint)Description.Length*2); //Size670 bw.Write(Encoding.Unicode.GetBytes(Description)); //Project Description671 672 //Helpfiles673 bw.Write((ushort)6); //ID674 bw.Write((uint)HelpFile1.Length); //Size675 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile1)); //HelpFile1676 bw.Write((ushort)0x3D); //ID677 bw.Write((uint)HelpFile2.Length); //Size678 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile2)); //HelpFile2679 680 //Help context id681 bw.Write((ushort)7); //ID682 bw.Write((uint)4); //Size683 bw.Write((uint)HelpContextID); //Help context id684 685 //Libflags686 bw.Write((ushort)8); //ID687 bw.Write((uint)4); //Size688 bw.Write((uint)0); //Help context id689 690 //Vba Version691 bw.Write((ushort)9); //ID692 bw.Write((uint)4); //Reserved693 bw.Write((uint)MajorVersion); //Reserved694 bw.Write((ushort)MinorVersion); //Help context id695 696 //Constants697 bw.Write((ushort)0x0C); //ID698 bw.Write((uint)Constants.Length); //Size699 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Constants)); //Help context id700 bw.Write((ushort)0x3C); //ID701 bw.Write((uint)Constants.Length/2); //Size702 bw.Write(Encoding.Unicode.GetBytes(Constants)); //HelpFile2703 704 /****** PROJECTREFERENCES Record ******/705 foreach (var reference in References)706 {707 WriteNameReference(bw, reference);708 709 if (reference.ReferenceRecordID == 0x2F)710 {711 WriteControlReference(bw, reference);712 }713 else if (reference.ReferenceRecordID == 0x33)714 {715 WriteOrginalReference(bw, reference);716 }717 else if (reference.ReferenceRecordID == 0x0D)718 {719 WriteRegisteredReference(bw, reference);720 }721 else if (reference.ReferenceRecordID == 0x0E)722 {723 WriteProjectReference(bw, reference);724 }725 }726 727 bw.Write((ushort)0x0F);728 bw.Write((uint)0x02);729 bw.Write((ushort)Modules.Count);730 bw.Write((ushort)0x13);731 bw.Write((uint)0x02);732 bw.Write((ushort)0xFFFF);733 734 foreach (var module in Modules)735 {736 WriteModuleRecord(bw, module);737 }738 bw.Write((ushort)0x10); //Terminator739 bw.Write((uint)0);740 741 return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray());742 }743 744 private void WriteModuleRecord(BinaryWriter bw, ExcelVBAModule module)745 {746 bw.Write((ushort)0x19);747 bw.Write((uint)module.Name.Length);748 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Name749 750 bw.Write((ushort)0x47);751 bw.Write((uint)module.Name.Length*2);752 bw.Write(Encoding.Unicode.GetBytes(module.Name)); //Name753 754 bw.Write((ushort)0x1A);755 bw.Write((uint)module.Name.Length);756 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Stream Name757 758 bw.Write((ushort)0x32);759 bw.Write((uint)module.Name.Length*2);760 bw.Write(Encoding.Unicode.GetBytes(module.Name)); //Stream Name761 762 module.Description = module.Description ?? "";763 bw.Write((ushort)0x1C);764 bw.Write((uint)module.Description.Length);765 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Description)); //Description766 767 bw.Write((ushort)0x48);768 bw.Write((uint)module.Description.Length*2);769 bw.Write(Encoding.Unicode.GetBytes(module.Description)); //Description770 771 bw.Write((ushort)0x31);772 bw.Write((uint)4);773 bw.Write((uint)0); //Module Stream Offset (No PerformanceCache)774 775 bw.Write((ushort)0x1E);776 bw.Write((uint)4);777 bw.Write((uint)module.HelpContext); //Help context ID778 779 bw.Write((ushort)0x2C);780 bw.Write((uint)2);781 bw.Write((ushort)0xFFFF); //Help context ID782 783 bw.Write((ushort)(module.Type == eModuleType.Module ? 0x21 : 0x22));784 bw.Write((uint)0);785 786 if (module.ReadOnly)787 {788 bw.Write((ushort)0x25);789 bw.Write((uint)0); //Readonly790 }791 792 if (module.Private)793 {794 bw.Write((ushort)0x28);795 bw.Write((uint)0); //Private796 }797 798 bw.Write((ushort)0x2B); //Terminator799 bw.Write((uint)0);800 }801 802 private void WriteNameReference(BinaryWriter bw, ExcelVbaReference reference)803 {804 //Name record805 bw.Write((ushort)0x16); //ID806 bw.Write((uint)reference.Name.Length); //Size807 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Name)); //HelpFile1808 bw.Write((ushort)0x3E); //ID809 bw.Write((uint)reference.Name.Length * 2); //Size810 bw.Write(Encoding.Unicode.GetBytes(reference.Name)); //HelpFile2811 }812 private void WriteControlReference(BinaryWriter bw, ExcelVbaReference reference)813 {814 WriteOrginalReference(bw, reference);815 816 bw.Write((ushort)0x2F);817 var controlRef=(ExcelVbaReferenceControl)reference;818 bw.Write((uint)(4 + controlRef.LibIdTwiddled.Length + 4 + 2)); // Size of SizeOfLibidTwiddled, LibidTwiddled, Reserved1, and Reserved2.819 bw.Write((uint)controlRef.LibIdTwiddled.Length); //Size820 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdTwiddled)); //LibID821 bw.Write((uint)0); //Reserved1822 bw.Write((ushort)0); //Reserved2823 WriteNameReference(bw, reference); //Name record again824 bw.Write((ushort)0x30); //Reserved3825 bw.Write((uint)(4 + controlRef.LibIdExternal.Length + 4 + 2 + 16 + 4)); //Size of SizeOfLibidExtended, LibidExtended, Reserved4, Reserved5, OriginalTypeLib, and Cookie826 bw.Write((uint)controlRef.LibIdExternal.Length); //Size827 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdExternal)); //LibID828 bw.Write((uint)0); //Reserved4829 bw.Write((ushort)0); //Reserved5830 bw.Write(controlRef.OriginalTypeLib.ToByteArray());831 bw.Write((uint)controlRef.Cookie); //Cookie832 }833 834 private void WriteOrginalReference(BinaryWriter bw, ExcelVbaReference reference)835 {836 bw.Write((ushort)0x33);837 bw.Write((uint)reference.Libid.Length);838 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid)); //LibID839 }840 private void WriteProjectReference(BinaryWriter bw, ExcelVbaReference reference)841 {842 bw.Write((ushort)0x0E);843 var projRef = (ExcelVbaReferenceProject)reference;844 bw.Write((uint)(4 + projRef.Libid.Length + 4 + projRef.LibIdRelative.Length+4+2));845 bw.Write((uint)projRef.Libid.Length);846 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.Libid)); //LibAbsolute847 bw.Write((uint)projRef.LibIdRelative.Length);848 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.LibIdRelative)); //LibIdRelative849 bw.Write(projRef.MajorVersion);850 bw.Write(projRef.MinorVersion);851 }852 853 private void WriteRegisteredReference(BinaryWriter bw, ExcelVbaReference reference)854 {855 bw.Write((ushort)0x0D);856 bw.Write((uint)(4+reference.Libid.Length+4+2));857 bw.Write((uint)reference.Libid.Length);858 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid)); //LibID859 bw.Write((uint)0); //Reserved1860 bw.Write((ushort)0); //Reserved2861 }862 863 private byte[] CreateProjectwmStream()864 {865 BinaryWriter bw = new BinaryWriter(new MemoryStream());866 867 foreach (var module in Modules)868 {869 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Name870 bw.Write((byte)0); //Null871 bw.Write(Encoding.Unicode.GetBytes(module.Name)); //Name872 bw.Write((ushort)0); //Null873 }874 bw.Write((ushort)0); //Null875 return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray());876 }877 private byte[] CreateProjectStream()878 {879 StringBuilder sb = new StringBuilder();880 sb.AppendFormat("ID=\"{0}\"\r\n", ProjectID);881 foreach(var module in Modules)882 {883 if (module.Type == eModuleType.Document)884 {885 sb.AppendFormat("Document={0}/&H00000000\r\n", module.Name);886 }887 else if (module.Type == eModuleType.Module)888 {889 sb.AppendFormat("Module={0}\r\n", module.Name);890 }891 else if (module.Type == eModuleType.Class)892 {893 sb.AppendFormat("Class={0}\r\n", module.Name);894 }895 else896 {897 //Designer898 sb.AppendFormat("Package={0}\r\n", module.ClassID);899 sb.AppendFormat("BaseClass={0}\r\n", module.Name);900 }901 }902 if (HelpFile1 != "")903 {904 sb.AppendFormat("HelpFile={0}\r\n", HelpFile1);905 }906 sb.AppendFormat("Name=\"{0}\"\r\n", Name);907 sb.AppendFormat("HelpContextID={0}\r\n", HelpContextID);908 909 if (!string.IsNullOrEmpty(Description))910 {911 sb.AppendFormat("Description=\"{0}\"\r\n", Description);912 }913 sb.AppendFormat("VersionCompatible32=\"393222000\"\r\n");914 915 sb.AppendFormat("CMG=\"{0}\"\r\n", WriteProtectionStat());916 sb.AppendFormat("DPB=\"{0}\"\r\n", WritePassword());917 sb.AppendFormat("GC=\"{0}\"\r\n\r\n", WriteVisibilityState());918 919 sb.Append("[Host Extender Info]\r\n");920 sb.Append("&H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000\r\n");921 sb.Append("\r\n");922 sb.Append("[Workspace]\r\n");923 foreach(var module in Modules)924 {925 sb.AppendFormat("{0}=0, 0, 0, 0, C \r\n",module.Name);926 }927 string s = sb.ToString();928 return Encoding.GetEncoding(CodePage).GetBytes(s);929 }930 private string WriteProtectionStat()931 {932 int stat=(_protection.UserProtected ? 1:0) |933 (_protection.HostProtected ? 2:0) |934 (_protection.VbeProtected ? 4:0);935 936 return Encrypt(BitConverter.GetBytes(stat));937 }938 private string WritePassword()939 {940 byte[] nullBits=new byte[3];941 byte[] nullKey = new byte[4];942 byte[] nullHash = new byte[20];943 if (Protection.PasswordKey == null)944 {945 return Encrypt(new byte[] { 0 });946 }947 else948 {949 Array.Copy(Protection.PasswordKey, nullKey, 4);950 Array.Copy(Protection.PasswordHash, nullHash, 20);951 952 //Set Null bits953 for (int i = 0; i < 24; i++)954 {955 byte bit = (byte)(128 >> (int)((i % 8)));956 if (i < 4)957 {958 if (nullKey[i] == 0)959 {960 nullKey[i] = 1;961 }962 else963 {964 nullBits[0] |= bit;965 }966 }967 else968 {969 if (nullHash[i - 4] == 0)970 {971 nullHash[i - 4] = 1;972 }973 else974 {975 int byteIndex = (i - i % 8) / 8;976 nullBits[byteIndex] |= bit;977 }978 }979 }980 //Write the Password Hash Data Structure (2.4.4.1)981 BinaryWriter bw = new BinaryWriter(new MemoryStream());982 bw.Write((byte)0xFF);983 bw.Write(nullBits);984 bw.Write(nullKey);985 bw.Write(nullHash);986 bw.Write((byte)0);987 return Encrypt(((MemoryStream)bw.BaseStream).ToArray());988 }989 }990 private string WriteVisibilityState()991 {992 return Encrypt(new byte[] { (byte)(Protection.VisibilityState ? 0xFF : 0) });993 }994 #endregion995 private string GetString(BinaryReader br, uint size)996 {997 return GetString(br, size, System.Text.Encoding.GetEncoding(CodePage));998 }999 private string GetString(BinaryReader br, uint size, Encoding enc)1000 {1001 if (size > 0)1002 {1003 byte[] byteTemp = new byte[size];1004 byteTemp = br.ReadBytes((int)size);1005 return enc.GetString(byteTemp);1006 }1007 else1008 {1009 return "";1010 }1011 }1012 private string GetUnicodeString(BinaryReader br, uint size)1013 {1014 string s = GetString(br, size);1015 int reserved = br.ReadUInt16();1016 uint sizeUC = br.ReadUInt32();1017 string sUC = GetString(br, sizeUC, System.Text.Encoding.Unicode);1018 return sUC.Length == 0 ? s : sUC;1019 }1020 internal CompoundDocument Document { get; set; }1021 #endif1022 internal Packaging.ZipPackagePart Part { get; set; }1023 internal Uri Uri { get; private set; }1024 #if !MONO1025 /// <summary>1026 /// Create a new VBA Project1027 /// </summary>1028 internal void Create()1029 {1030 if(Lcid>0)1031 {1032 throw (new InvalidOperationException("Package already contains a VBAProject"));1033 }1034 ProjectID = "{5DD90D76-4904-47A2-AF0D-D69B4673604E}";1035 Name = "VBAProject";1036 SystemKind = eSyskind.Win32; //Default1037 Lcid = 1033; //English - United States1038 LcidInvoke = 1033; //English - United States1039 CodePage = Encoding.Default.CodePage;1040 MajorVersion = 1361024421;1041 MinorVersion = 6;1042 HelpContextID = 0;1043 Modules.Add(new ExcelVBAModule(_wb.CodeNameChange) { Name = "ThisWorkbook", Code = "", Attributes=GetDocumentAttributes("ThisWorkbook", "0{00020819-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 });1044 foreach (var sheet in _wb.Worksheets)1045 {1046 var name = GetModuleNameFromWorksheet(sheet);1047 if (!Modules.Exists(name))1048 {1049 Modules.Add(new ExcelVBAModule(sheet.CodeNameChange) { Name = name, Code = "", Attributes = GetDocumentAttributes(sheet.Name, "0{00020820-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 });1050 }1051 }1052 _protection = new ExcelVbaProtection(this) { UserProtected = false, HostProtected = false, VbeProtected = false, VisibilityState = true };1053 }1054 1055 internal string GetModuleNameFromWorksheet(ExcelWorksheet sheet)1056 {1057 var name = sheet.Name;1058 if (name.Any(c => c > 255) || this.Modules[name] != null)1059 {1060 int i = sheet.PositionID;1061 name = "Sheet" + i.ToString();1062 while (this.Modules[name] != null)1063 {1064 name = "Sheet" + (++i).ToString(); ;1065 }1066 }1067 return name;1068 }1069 internal ExcelVbaModuleAttributesCollection GetDocumentAttributes(string name, string clsid)1070 {1071 var attr = new ExcelVbaModuleAttributesCollection();1072 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = name, DataType = eAttributeDataType.String });1073 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = clsid, DataType = eAttributeDataType.String });1074 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString });1075 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString });1076 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "True", DataType = eAttributeDataType.NonString });1077 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = "False", DataType = eAttributeDataType.NonString });1078 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString });1079 attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "True", DataType = eAttributeDataType.NonString });1080 1081 return attr;1082 }1083 1084 1085 //internal string GetBlankDocumentModule(string name, string clsid)1086 //{1087 // string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name);1088 // ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", clsid); //Microsoft.Office.Interop.Excel.WorksheetClass1089 // ret += "Attribute VB_GlobalNameSpace = False\r\n";1090 // ret += "Attribute VB_Creatable = False\r\n";1091 // ret += "Attribute VB_PredeclaredId = True\r\n";1092 // ret += "Attribute VB_Exposed = True\r\n";1093 // ret += "Attribute VB_TemplateDerived = False\r\n";1094 // ret += "Attribute VB_Customizable = True";1095 // return ret;1096 //}1097 //internal string GetBlankModule(string name)1098 //{1099 // return string.Format("Attribute VB_Name = \"{0}\"\r\n", name);1100 //}1101 //internal string GetBlankClassModule(string name, bool exposed)1102 //{1103 // string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name);1104 // ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}");1105 // ret += "Attribute VB_GlobalNameSpace = False\r\n";1106 // ret += "Attribute VB_Creatable = False\r\n";1107 // ret += "Attribute VB_PredeclaredId = False\r\n";1108 // ret += string.Format("Attribute VB_Exposed = {0}\r\n", exposed ? "True" : "False");1109 // ret += "Attribute VB_TemplateDerived = False\r\n";1110 // ret += "Attribute VB_Customizable = False\r\n";1111 // return ret;1112 //}1113 #endif1114 /// <summary>1115 /// Remove the project from the package1116 /// </summary>1117 public void Remove()1118 {1119 if (Part == null) return;1120 1121 foreach (var rel in Part.GetRelationships())1122 {1123 _pck.DeleteRelationship(rel.Id);1124 }1125 if (_pck.PartExists(Uri))1126 {1127 _pck.DeletePart(Uri);1128 }1129 Part = null;1130 Modules.Clear();1131 References.Clear();1132 Lcid = 0;1133 LcidInvoke = 0;1134 CodePage = 0;1135 MajorVersion = 0;1136 MinorVersion = 0;1137 HelpContextID = 0;1138 }1139 public override string ToString()1140 {1141 return Name;1142 }1143 }1144 } -
VBA/ExcelVBAReference.cs
1 /*******************************************************************************2 * You may amend and distribute as you like, but don't remove this header!3 *4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.5 * See http://www.codeplex.com/EPPlus for details.6 *7 * Copyright (C) 2011 Jan KÀllman8 *9 * This library is free software; you can redistribute it and/or10 * modify it under the terms of the GNU Lesser General Public11 * License as published by the Free Software Foundation; either12 * version 2.1 of the License, or (at your option) any later version.13 14 * This library is distributed in the hope that it will be useful,15 * but WITHOUT ANY WARRANTY; without even the implied warranty of16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.17 * See the GNU Lesser General Public License for more details.18 *19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html21 *22 * All code and executables are provided "as is" with no warranty either express or implied.23 * The author accepts no liability for any damage or loss of business that this product may cause.24 *25 * Code change notes:26 *27 * Author Change Date28 *******************************************************************************29 * Jan KÀllman Added 26-MAR-201230 *******************************************************************************/31 using System;32 using System.Collections.Generic;33 using System.Linq;34 using System.Text;35 36 namespace OfficeOpenXml.VBA37 {38 /// <summary>39 /// A VBA reference40 /// </summary>41 public class ExcelVbaReference42 {43 /// <summary>44 /// Constructor.45 /// Defaults ReferenceRecordID to 0xD46 /// </summary>47 public ExcelVbaReference()48 {49 ReferenceRecordID = 0xD;50 }51 /// <summary>52 /// The reference record ID. See MS-OVBA documentation for more info.53 /// </summary>54 public int ReferenceRecordID { get; internal set; }55 /// <summary>56 /// The name of the reference57 /// </summary>58 public string Name { get; set; }59 /// <summary>60 /// LibID61 /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES62 /// </summary>63 public string Libid { get; set; }64 /// <summary>65 /// A string representation of the object (the Name)66 /// </summary>67 /// <returns></returns>68 public override string ToString()69 {70 return Name;71 }72 }73 /// <summary>74 /// A reference to a twiddled type library75 /// </summary>76 public class ExcelVbaReferenceControl : ExcelVbaReference77 {78 /// <summary>79 /// Constructor.80 /// Sets ReferenceRecordID to 0x2F81 /// </summary>82 public ExcelVbaReferenceControl()83 {84 ReferenceRecordID = 0x2F;85 }86 /// <summary>87 /// LibIdExternal88 /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES89 /// </summary>90 public string LibIdExternal { get; set; }91 /// <summary>92 /// LibIdTwiddled93 /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES94 /// </summary>95 public string LibIdTwiddled { get; set; }96 /// <summary>97 /// A GUID that specifies the Automation type library the extended type library was generated from.98 /// </summary>99 public Guid OriginalTypeLib { get; set; }100 internal uint Cookie { get; set; }101 }102 /// <summary>103 /// A reference to an external VBA project104 /// </summary>105 public class ExcelVbaReferenceProject : ExcelVbaReference106 {107 /// <summary>108 /// Constructor.109 /// Sets ReferenceRecordID to 0x0E110 /// </summary>111 public ExcelVbaReferenceProject()112 {113 ReferenceRecordID = 0x0E;114 }115 /// <summary>116 /// LibIdRelative117 /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES118 /// </summary>119 public string LibIdRelative { get; set; }120 /// <summary>121 /// Major version of the referenced VBA project122 /// </summary>123 public uint MajorVersion { get; set; }124 /// <summary>125 /// Minor version of the referenced VBA project126 /// </summary>127 public ushort MinorVersion { get; set; }128 }129 } -
VBA/ExcelVBASignature.cs
1 /*******************************************************************************2 * You may amend and distribute as you like, but don't remove this header!3 *4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.5 * See http://www.codeplex.com/EPPlus for details.6 *7 * Copyright (C) 2011 Jan KÀllman8 *9 * This library is free software; you can redistribute it and/or10 * modify it under the terms of the GNU Lesser General Public11 * License as published by the Free Software Foundation; either12 * version 2.1 of the License, or (at your option) any later version.13 14 * This library is distributed in the hope that it will be useful,15 * but WITHOUT ANY WARRANTY; without even the implied warranty of16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.17 * See the GNU Lesser General Public License for more details.18 *19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html21 *22 * All code and executables are provided "as is" with no warranty either express or implied.23 * The author accepts no liability for any damage or loss of business that this product may cause.24 *25 * Code change notes:26 *27 * Author Change Date28 *******************************************************************************29 * Jan KÀllman Added 26-MAR-201230 *******************************************************************************/31 using System;32 using System.Collections.Generic;33 using System.Linq;34 using System.Text;35 using System.Security.Cryptography.X509Certificates;36 using System.Security.Cryptography.Pkcs;37 using OfficeOpenXml.Utils;38 using System.IO;39 40 namespace OfficeOpenXml.VBA41 {42 /// <summary>43 /// The code signature properties of the project44 /// </summary>45 public class ExcelVbaSignature46 {47 const string schemaRelVbaSignature = "http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature";48 Packaging.ZipPackagePart _vbaPart = null;49 internal ExcelVbaSignature(Packaging.ZipPackagePart vbaPart)50 {51 _vbaPart = vbaPart;52 GetSignature();53 }54 private void GetSignature()55 {56 if (_vbaPart == null) return;57 var rel = _vbaPart.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault();58 if (rel != null)59 {60 Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);61 Part = _vbaPart.Package.GetPart(Uri);62 63 var stream = Part.GetStream();64 BinaryReader br = new BinaryReader(stream);65 uint cbSignature = br.ReadUInt32();66 uint signatureOffset = br.ReadUInt32(); //44 ??67 uint cbSigningCertStore = br.ReadUInt32();68 uint certStoreOffset = br.ReadUInt32();69 uint cbProjectName = br.ReadUInt32();70 uint projectNameOffset = br.ReadUInt32();71 uint fTimestamp = br.ReadUInt32();72 uint cbTimestampUrl = br.ReadUInt32();73 uint timestampUrlOffset = br.ReadUInt32();74 byte[] signature = br.ReadBytes((int)cbSignature);75 uint version = br.ReadUInt32();76 uint fileType = br.ReadUInt32();77 78 uint id = br.ReadUInt32();79 while (id != 0)80 {81 uint encodingType = br.ReadUInt32();82 uint length = br.ReadUInt32();83 if (length > 0)84 {85 byte[] value = br.ReadBytes((int)length);86 switch (id)87 {88 //Add property values here...89 case 0x20:90 Certificate = new X509Certificate2(value);91 break;92 default:93 break;94 }95 }96 id = br.ReadUInt32();97 }98 uint endel1 = br.ReadUInt32(); //099 uint endel2 = br.ReadUInt32(); //0100 ushort rgchProjectNameBuffer = br.ReadUInt16();101 ushort rgchTimestampBuffer = br.ReadUInt16();102 Verifier = new SignedCms();103 Verifier.Decode(signature);104 }105 else106 {107 Certificate = null;108 Verifier = null;109 }110 }111 //Create Oid from a bytearray112 //private string ReadHash(byte[] content)113 //{114 // StringBuilder builder = new StringBuilder();115 // int offset = 0x6;116 // if (0 < (content.Length))117 // {118 // byte num = content[offset];119 // byte num2 = (byte)(num / 40);120 // builder.Append(num2.ToString(null, null));121 // builder.Append(".");122 // num2 = (byte)(num % 40);123 // builder.Append(num2.ToString(null, null));124 // ulong num3 = 0L;125 // for (int i = offset + 1; i < content.Length; i++)126 // {127 // num2 = content[i];128 // num3 = (ulong)(ulong)(num3 << 7) + ((byte)(num2 & 0x7f));129 // if ((num2 & 0x80) == 0)130 // {131 // builder.Append(".");132 // builder.Append(num3.ToString(null, null));133 // num3 = 0L;134 // }135 // //1.2.840.113549.2.5136 // }137 // }138 139 140 // string oId = builder.ToString();141 142 // return oId;143 //}144 internal void Save(ExcelVbaProject proj)145 {146 if (Certificate == null)147 {148 return;149 }150 151 if (Certificate.HasPrivateKey==false) //No signature. Remove any Signature part152 {153 var storeCert = GetCertFromStore(StoreLocation.CurrentUser);154 if (storeCert == null)155 {156 storeCert = GetCertFromStore(StoreLocation.LocalMachine);157 }158 if (storeCert != null && storeCert.HasPrivateKey == true)159 {160 Certificate = storeCert;161 }162 else163 {164 foreach (var r in Part.GetRelationships())165 {166 Part.DeleteRelationship(r.Id);167 }168 Part.Package.DeletePart(Part.Uri);169 return;170 }171 }172 var ms = new MemoryStream();173 var bw = new BinaryWriter(ms);174 175 byte[] certStore = GetCertStore();176 177 byte[] cert = SignProject(proj);178 bw.Write((uint)cert.Length);179 bw.Write((uint)44); //?? 36 ref inside cert ??180 bw.Write((uint)certStore.Length); //cbSigningCertStore181 bw.Write((uint)(cert.Length + 44)); //certStoreOffset182 bw.Write((uint)0); //cbProjectName183 bw.Write((uint)(cert.Length + certStore.Length + 44)); //projectNameOffset184 bw.Write((uint)0); //fTimestamp185 bw.Write((uint)0); //cbTimestampUrl186 bw.Write((uint)(cert.Length + certStore.Length + 44 + 2)); //timestampUrlOffset187 bw.Write(cert);188 bw.Write(certStore);189 bw.Write((ushort)0);//rgchProjectNameBuffer190 bw.Write((ushort)0);//rgchTimestampBuffer191 bw.Write((ushort)0);192 bw.Flush();193 194 var rel = proj.Part.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault();195 if (Part == null)196 {197 198 if (rel != null)199 {200 Uri = rel.TargetUri;201 Part = proj._pck.GetPart(rel.TargetUri);202 }203 else204 {205 Uri = new Uri("/xl/vbaProjectSignature.bin", UriKind.Relative);206 Part = proj._pck.CreatePart(Uri, ExcelPackage.schemaVBASignature);207 }208 }209 if (rel == null)210 {211 proj.Part.CreateRelationship(UriHelper.ResolvePartUri(proj.Uri, Uri), Packaging.TargetMode.Internal, schemaRelVbaSignature);212 }213 var b = ms.ToArray();214 Part.GetStream(FileMode.Create).Write(b, 0, b.Length);215 }216 217 private X509Certificate2 GetCertFromStore(StoreLocation loc)218 {219 try220 {221 X509Store store = new X509Store(loc);222 store.Open(OpenFlags.ReadOnly);223 try224 {225 var storeCert = store.Certificates.Find(226 X509FindType.FindByThumbprint,227 Certificate.Thumbprint,228 true229 ).OfType<X509Certificate2>().FirstOrDefault();230 return storeCert;231 }232 finally233 {234 store.Close();235 }236 }237 catch238 {239 return null;240 }241 }242 243 private byte[] GetCertStore()244 {245 var ms = new MemoryStream();246 var bw = new BinaryWriter(ms);247 248 bw.Write((uint)0); //Version249 bw.Write((uint)0x54524543); //fileType250 251 //SerializedCertificateEntry252 var certData = Certificate.RawData;253 bw.Write((uint)0x20);254 bw.Write((uint)1);255 bw.Write((uint)certData.Length);256 bw.Write(certData);257 258 //EndElementMarkerEntry259 bw.Write((uint)0);260 bw.Write((ulong)0);261 262 bw.Flush();263 return ms.ToArray();264 }265 266 private void WriteProp(BinaryWriter bw, int id, byte[] data)267 {268 bw.Write((uint)id);269 bw.Write((uint)1);270 bw.Write((uint)data.Length);271 bw.Write(data);272 }273 internal byte[] SignProject(ExcelVbaProject proj)274 {275 if (!Certificate.HasPrivateKey)276 {277 //throw (new InvalidOperationException("The certificate doesn't have a private key"));278 Certificate = null;279 return null;280 }281 var hash = GetContentHash(proj);282 283 BinaryWriter bw = new BinaryWriter(new MemoryStream());284 bw.Write((byte)0x30); //Constructed Type285 bw.Write((byte)0x32); //Total length286 bw.Write((byte)0x30); //Constructed Type287 bw.Write((byte)0x0E); //Length SpcIndirectDataContent288 bw.Write((byte)0x06); //Oid Tag Indentifier289 bw.Write((byte)0x0A); //Lenght OId290 bw.Write(new byte[] { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x1D }); //Encoded Oid 1.3.6.1.4.1.311.2.1.29291 bw.Write((byte)0x04); //Octet String Tag Identifier292 bw.Write((byte)0x00); //Zero length293 294 bw.Write((byte)0x30); //Constructed Type (DigestInfo)295 bw.Write((byte)0x20); //Length DigestInfo296 bw.Write((byte)0x30); //Constructed Type (Algorithm)297 bw.Write((byte)0x0C); //length AlgorithmIdentifier298 bw.Write((byte)0x06); //Oid Tag Indentifier299 bw.Write((byte)0x08); //Lenght OId300 bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5)301 bw.Write((byte)0x05); //Null type identifier302 bw.Write((byte)0x00); //Null length303 bw.Write((byte)0x04); //Octet String Identifier304 bw.Write((byte)hash.Length); //Hash length305 bw.Write(hash); //Content hash306 307 ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray());308 contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4";309 Verifier = new SignedCms(contentInfo);310 var signer = new CmsSigner(Certificate);311 Verifier.ComputeSignature(signer, false);312 return Verifier.Encode();313 }314 315 private byte[] GetContentHash(ExcelVbaProject proj)316 {317 //MS-OVBA 2.4.2318 var enc = System.Text.Encoding.GetEncoding(proj.CodePage);319 BinaryWriter bw = new BinaryWriter(new MemoryStream());320 bw.Write(enc.GetBytes(proj.Name));321 bw.Write(enc.GetBytes(proj.Constants));322 foreach (var reference in proj.References)323 {324 if (reference.ReferenceRecordID == 0x0D)325 {326 bw.Write((byte)0x7B);327 }328 if (reference.ReferenceRecordID == 0x0E)329 {330 //var r = (ExcelVbaReferenceProject)reference;331 //BinaryWriter bwTemp = new BinaryWriter(new MemoryStream());332 //bwTemp.Write((uint)r.Libid.Length);333 //bwTemp.Write(enc.GetBytes(r.Libid));334 //bwTemp.Write((uint)r.LibIdRelative.Length);335 //bwTemp.Write(enc.GetBytes(r.LibIdRelative));336 //bwTemp.Write(r.MajorVersion);337 //bwTemp.Write(r.MinorVersion);338 foreach (byte b in BitConverter.GetBytes((uint)reference.Libid.Length)) //Length will never be an UInt with 4 bytes that aren't 0 (> 0x00FFFFFF), so no need for the rest of the properties.339 {340 if (b != 0)341 {342 bw.Write(b);343 }344 else345 {346 break;347 }348 }349 }350 }351 foreach (var module in proj.Modules)352 {353 var lines = module.Code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);354 foreach (var line in lines)355 {356 if (!line.StartsWith("attribute", true, null))357 {358 bw.Write(enc.GetBytes(line));359 }360 }361 }362 var buffer = (bw.BaseStream as MemoryStream).ToArray();363 var hp = System.Security.Cryptography.MD5CryptoServiceProvider.Create();364 return hp.ComputeHash(buffer);365 }366 /// <summary>367 /// The certificate to sign the VBA project.368 /// <remarks>369 /// This certificate must have a private key.370 /// There is no validation that the certificate is valid for codesigning, so make sure it's valid to sign Excel files (Excel 2010 is more strict that prior versions).371 /// </remarks>372 /// </summary>373 public X509Certificate2 Certificate { get; set; }374 /// <summary>375 /// The verifier376 /// </summary>377 public SignedCms Verifier { get; internal set; }378 #if !MONO379 internal CompoundDocument Signature { get; set; }380 #endif381 internal Packaging.ZipPackagePart Part { get; set; }382 internal Uri Uri { get; private set; }383 }384 }
Note: See TracBrowser
for help on using the repository browser.