Index: ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs =================================================================== --- ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs (Revision 12462) +++ ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs (Arbeitskopie) @@ -1,358 +0,0 @@ -/******************************************************************************* - * You may amend and distribute as you like, but don't remove this header! - * - * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. - * See http://www.codeplex.com/EPPlus for details. - * - * Copyright (C) 2011 Jan Källman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php - * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html - * - * All code and executables are provided "as is" with no warranty either express or implied. - * The author accepts no liability for any damage or loss of business that this product may cause. - * - * Code change notes: - * - * Author Change Date - * ****************************************************************************** - * Eyal Seagull Added 2012-04-03 - *******************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Drawing; -using System.Xml; -using OfficeOpenXml.Utils; -using System.Text.RegularExpressions; -using System.Globalization; -using System.Security; - -namespace OfficeOpenXml.ConditionalFormatting -{ - /// - /// 18.3.1.11 cfvo (Conditional Format Value Object) - /// Describes the values of the interpolation points in a gradient scale. - /// - public class ExcelConditionalFormattingIconDataBarValue - : XmlHelper - { - /****************************************************************************************/ - - #region Private Properties - private eExcelConditionalFormattingRuleType _ruleType; - private ExcelWorksheet _worksheet; - #endregion Private Properties - - /****************************************************************************************/ - - #region Constructors - /// - /// Initialize the cfvo (§18.3.1.11) node - /// - /// - /// - /// - /// - /// - /// - /// - /// The cfvo (§18.3.1.11) node parent. Can be any of the following: - /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49) - /// - internal ExcelConditionalFormattingIconDataBarValue( - eExcelConditionalFormattingValueObjectType type, - double value, - string formula, - eExcelConditionalFormattingRuleType ruleType, - ExcelAddress address, - int priority, - ExcelWorksheet worksheet, - XmlNode itemElementNode, - XmlNamespaceManager namespaceManager) - : this( - ruleType, - address, - worksheet, - itemElementNode, - namespaceManager) - { - Require.Argument(priority).IsInRange(1, int.MaxValue, "priority"); - - // Check if the parent does not exists - if (itemElementNode == null) - { - // Get the parent node path by the rule type - string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType( - ruleType); - - // Check for en error (rule type does not have ) - if (parentNodePath == string.Empty) - { - throw new Exception( - ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode); - } - - // Point to the parent node - itemElementNode = _worksheet.WorksheetXml.SelectSingleNode( - string.Format( - "//{0}[{1}='{2}']/{3}[{4}='{5}']/{6}", - // {0} - ExcelConditionalFormattingConstants.Paths.ConditionalFormatting, - // {1} - ExcelConditionalFormattingConstants.Paths.SqrefAttribute, - // {2} - address.Address, - // {3} - ExcelConditionalFormattingConstants.Paths.CfRule, - // {4} - ExcelConditionalFormattingConstants.Paths.PriorityAttribute, - // {5} - priority, - // {6} - parentNodePath), - _worksheet.NameSpaceManager); - - // Check for en error (rule type does not have ) - if (itemElementNode == null) - { - throw new Exception( - ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode); - } - } - - TopNode = itemElementNode; - - // Save the attributes - RuleType = ruleType; - Type = type; - Value = value; - Formula = formula; - } - /// - /// Initialize the cfvo (§18.3.1.11) node - /// - /// - /// - /// - /// The cfvo (§18.3.1.11) node parent. Can be any of the following: - /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49) - /// - internal ExcelConditionalFormattingIconDataBarValue( - eExcelConditionalFormattingRuleType ruleType, - ExcelAddress address, - ExcelWorksheet worksheet, - XmlNode itemElementNode, - XmlNamespaceManager namespaceManager) - : base( - namespaceManager, - itemElementNode) - { - Require.Argument(address).IsNotNull("address"); - Require.Argument(worksheet).IsNotNull("worksheet"); - - // Save the worksheet for private methods to use - _worksheet = worksheet; - - // Schema order list - SchemaNodeOrder = new string[] - { - ExcelConditionalFormattingConstants.Nodes.Cfvo, - }; - - //Check if the parent does not exists - if (itemElementNode == null) - { - // Get the parent node path by the rule type - string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType( - ruleType); - - // Check for en error (rule type does not have ) - if (parentNodePath == string.Empty) - { - throw new Exception( - ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode); - } - } - RuleType = ruleType; - } - /// - /// Initialize the - /// - /// - /// - /// - /// - /// - /// - /// - /// - internal ExcelConditionalFormattingIconDataBarValue( - eExcelConditionalFormattingValueObjectType type, - double value, - string formula, - eExcelConditionalFormattingRuleType ruleType, - ExcelAddress address, - int priority, - ExcelWorksheet worksheet, - XmlNamespaceManager namespaceManager) - : this( - type, - value, - formula, - ruleType, - address, - priority, - worksheet, - null, - namespaceManager) - { - - } - /// - /// Initialize the - /// - /// - /// - /// - /// - /// - /// - /// - internal ExcelConditionalFormattingIconDataBarValue( - eExcelConditionalFormattingValueObjectType type, - Color color, - eExcelConditionalFormattingRuleType ruleType, - ExcelAddress address, - int priority, - ExcelWorksheet worksheet, - XmlNamespaceManager namespaceManager) - : this( - type, - 0, - null, - ruleType, - address, - priority, - worksheet, - null, - namespaceManager) - { - } - #endregion Constructors - - /****************************************************************************************/ - - #region Methods - #endregion - - /****************************************************************************************/ - - #region Exposed Properties - - /// - /// - /// - internal eExcelConditionalFormattingRuleType RuleType - { - get { return _ruleType; } - set { _ruleType = value; } - } - - /// - /// - /// - public eExcelConditionalFormattingValueObjectType Type - { - get - { - var typeAttribute = GetXmlNodeString(ExcelConditionalFormattingConstants.Paths.TypeAttribute); - - return ExcelConditionalFormattingValueObjectType.GetTypeByAttrbiute(typeAttribute); - } - set - { - if ((_ruleType==eExcelConditionalFormattingRuleType.ThreeIconSet || _ruleType==eExcelConditionalFormattingRuleType.FourIconSet || _ruleType==eExcelConditionalFormattingRuleType.FiveIconSet) && - (value == eExcelConditionalFormattingValueObjectType.Min || value == eExcelConditionalFormattingValueObjectType.Max)) - { - throw(new ArgumentException("Value type can't be Min or Max for icon sets")); - } - SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.TypeAttribute, value.ToString().ToLower(CultureInfo.InvariantCulture)); - } - } - - /// - /// Get/Set the 'cfvo' node @val attribute - /// - public Double Value - { - get - { - if ((Type == eExcelConditionalFormattingValueObjectType.Num) - || (Type == eExcelConditionalFormattingValueObjectType.Percent) - || (Type == eExcelConditionalFormattingValueObjectType.Percentile)) - { - return GetXmlNodeDouble(ExcelConditionalFormattingConstants.Paths.ValAttribute); - } - else - { - return 0; - } - } - set - { - string valueToStore = string.Empty; - - // Only some types use the @val attribute - if ((Type == eExcelConditionalFormattingValueObjectType.Num) - || (Type == eExcelConditionalFormattingValueObjectType.Percent) - || (Type == eExcelConditionalFormattingValueObjectType.Percentile)) - { - valueToStore = value.ToString(CultureInfo.InvariantCulture); - } - - SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute, valueToStore); - } - } - - /// - /// Get/Set the Formula of the Object Value (uses the same attribute as the Value) - /// - public string Formula - { - get - { - // Return empty if the Object Value type is not Formula - if (Type != eExcelConditionalFormattingValueObjectType.Formula) - { - return string.Empty; - } - - // Excel stores the formula in the @val attribute - return GetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute); - } - set - { - // Only store the formula if the Object Value type is Formula - if (Type == eExcelConditionalFormattingValueObjectType.Formula) - { - SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute, value); - } - } - } - #endregion Exposed Properties - - /****************************************************************************************/ - } -} \ No newline at end of file Index: ExcelWorkbook.cs =================================================================== --- ExcelWorkbook.cs (Revision 12462) +++ ExcelWorkbook.cs (Arbeitskopie) @@ -336,6 +336,9 @@ if (_standardFontWidth == decimal.MinValue || _fontID != Styles.Fonts[0].Id) { var font = Styles.Fonts[0]; +#if __MonoCS__ + _standardFontWidth = (int)(font.Size * (2D / 3D)); //Aprox for Calibri. +#else try { //Font f = new Font(font.Name, font.Size); @@ -373,6 +376,7 @@ { _standardFontWidth = (int)(font.Size * (2D / 3D)); //Aprox for Calibri. } +#endif } return _standardFontWidth; } Index: VBA/ExcelVBAModuleCollection.cs =================================================================== --- VBA/ExcelVBAModuleCollection.cs (Revision 12462) +++ VBA/ExcelVBAModuleCollection.cs (Arbeitskopie) @@ -1,210 +0,0 @@ -/******************************************************************************* - * You may amend and distribute as you like, but don't remove this header! - * - * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. - * See http://www.codeplex.com/EPPlus for details. - * - * Copyright (C) 2011 Jan Källman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php - * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html - * - * All code and executables are provided "as is" with no warranty either express or implied. - * The author accepts no liability for any damage or loss of business that this product may cause. - * - * Code change notes: - * - * Author Change Date - ******************************************************************************* - * Jan Källman Added 12-APR-2012 - *******************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace OfficeOpenXml.VBA -{ - /// - /// Base class for VBA collections - /// - /// - public class ExcelVBACollectionBase : IEnumerable - { - internal protected List _list=new List(); - public IEnumerator GetEnumerator() - { - return _list.GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return _list.GetEnumerator(); - } - /// - /// Indexer - /// - /// Name - /// - public T this [string Name] - { - get - { - return _list.Find((f) => f.GetType().GetProperty("Name").GetValue(f, null).ToString().Equals(Name,StringComparison.InvariantCultureIgnoreCase)); - } - } - /// - /// Indexer - /// - /// Position - /// - public T this[int Index] - { - get - { - return _list[Index]; - } - } - /// - /// Number of items in the collection - /// - public int Count - { - get { return _list.Count; } - } - /// - /// If a specific name exists in the collection - /// - /// The name - /// True if the name exists - public bool Exists(string Name) - { - return _list.Exists((f) => f.GetType().GetProperty("Name").GetValue(f, null).ToString().Equals(Name,StringComparison.InvariantCultureIgnoreCase)); - } - /// - /// Removes the item - /// - /// - public void Remove(T Item) - { - _list.Remove(Item); - } - /// - /// Removes the item at the specified index - /// - /// THe index - public void RemoveAt(int index) - { - _list.RemoveAt(index); - } - - internal void Clear() - { - _list.Clear(); - } - } - /// - /// Collection class for VBA modules - /// - public class ExcelVbaModuleCollection : ExcelVBACollectionBase - { - ExcelVbaProject _project; - internal ExcelVbaModuleCollection (ExcelVbaProject project) - { - _project=project; - } - internal void Add(ExcelVBAModule Item) - { - _list.Add(Item); - } - /// - /// Adds a new VBA Module - /// - /// The name of the module - /// The module object - public ExcelVBAModule AddModule(string Name) - { - if (this[Name] != null) - { - throw(new ArgumentException("Vba modulename already exist.")); - } - var m = new ExcelVBAModule(); - m.Name = Name; - m.Type = eModuleType.Module; - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = Name, DataType = eAttributeDataType.String }); - m.Type = eModuleType.Module; - _list.Add(m); - return m; - } - /// - /// Adds a new VBA class - /// - /// The name of the class - /// Private or Public not createble - /// The class object - public ExcelVBAModule AddClass(string Name, bool Exposed) - { - var m = new ExcelVBAModule(); - m.Name = Name; - m.Type = eModuleType.Class; - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = Name, DataType = eAttributeDataType.String }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}", DataType = eAttributeDataType.String }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "False", DataType = eAttributeDataType.NonString }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = Exposed ? "True" : "False", DataType = eAttributeDataType.NonString }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString }); - m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "False", DataType = eAttributeDataType.NonString }); - - //m.Code = _project.GetBlankClassModule(Name, Exposed); - m.Private = !Exposed; - //m.ClassID= - _list.Add(m); - return m; - } - } - /// - /// A collection of the vba projects references - /// - public class ExcelVbaReferenceCollection : ExcelVBACollectionBase - { - internal ExcelVbaReferenceCollection() - { - - } - /// - /// Adds a new reference - /// - /// The reference object - public void Add(ExcelVbaReference Item) - { - _list.Add(Item); - } - } - /// - /// A collection of the module level attributes - /// - public class ExcelVbaModuleAttributesCollection : ExcelVBACollectionBase - { - internal string GetAttributeText() - { - StringBuilder sb=new StringBuilder(); - - foreach (var attr in this) - { - sb.AppendFormat("Attribute {0} = {1}\r\n", attr.Name, attr.DataType==eAttributeDataType.String ? "\"" + attr.Value + "\"" : attr.Value); - } - return sb.ToString(); - } - } -} Index: VBA/ExcelVBAProject.cs =================================================================== --- VBA/ExcelVBAProject.cs (Revision 12462) +++ VBA/ExcelVBAProject.cs (Arbeitskopie) @@ -1,1144 +0,0 @@ -/******************************************************************************* - * You may amend and distribute as you like, but don't remove this header! - * - * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. - * See http://www.codeplex.com/EPPlus for details. - * - * Copyright (C) 2011 Jan Källman - * - * All code and executables are provided "as is" with no warranty either express or implied. - * The author accepts no liability for any damage or loss of business that this product may cause. - * - * If you want to understand this code have a look at the Office VBA File Format Structure Specification (MS-OVBA.PDF) or - * http://msdn.microsoft.com/en-us/library/cc313094(v=office.12).aspx - * - * * Code change notes: - * - * Author Change Date - ******************************************************************************* - * Jan Källman Added 26-MAR-2012 - *******************************************************************************/ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.IO; -using OfficeOpenXml.Utils; -using System.Security.Cryptography.Pkcs; -using System.Security.Cryptography.X509Certificates; -using System.Security.Cryptography; -using System.Text.RegularExpressions; - -namespace OfficeOpenXml.VBA -{ - /// - /// Represents the VBA project part of the package - /// - public class ExcelVbaProject - { - const string schemaRelVba = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"; - internal const string PartUri = @"/xl/vbaProject.bin"; - #region Classes & Enums - /// - /// Type of system where the VBA project was created. - /// - public enum eSyskind - { - Win16 = 0, - Win32 = 1, - Macintosh = 2, - Win64 = 3 - } - - #endregion - internal ExcelVbaProject(ExcelWorkbook wb) - { - _wb = wb; - _pck = _wb._package.Package; - References = new ExcelVbaReferenceCollection(); - Modules = new ExcelVbaModuleCollection(this); - var rel = _wb.Part.GetRelationshipsByType(schemaRelVba).FirstOrDefault(); - if (rel != null) - { - Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri); - Part = _pck.GetPart(Uri); -#if !MONO - GetProject(); -#endif - } - else - { - Lcid = 0; - Part = null; - } - } - internal ExcelWorkbook _wb; - internal Packaging.ZipPackage _pck; - #region Dir Stream Properties - /// - /// System kind. Default Win32. - /// - public eSyskind SystemKind { get; set; } - /// - /// Name of the project - /// - public string Name { get; set; } - /// - /// A description of the project - /// - public string Description { get; set; } - /// - /// A helpfile - /// - public string HelpFile1 { get; set; } - /// - /// Secondary helpfile - /// - public string HelpFile2 { get; set; } - /// - /// Context if refering the helpfile - /// - public int HelpContextID { get; set; } - /// - /// Conditional compilation constants - /// - public string Constants { get; set; } - /// - /// Codepage for encoding. Default is current regional setting. - /// - public int CodePage { get; internal set; } - internal int LibFlags { get; set; } - internal int MajorVersion { get; set; } - internal int MinorVersion { get; set; } - internal int Lcid { get; set; } - internal int LcidInvoke { get; set; } - internal string ProjectID { get; set; } - internal string ProjectStreamText { get; set; } - /// - /// Project references - /// - public ExcelVbaReferenceCollection References { get; set; } - /// - /// Code Modules (Modules, classes, designer code) - /// - public ExcelVbaModuleCollection Modules { get; set; } - ExcelVbaSignature _signature = null; - /// - /// The digital signature - /// - public ExcelVbaSignature Signature - { - get - { - if (_signature == null) - { - _signature=new ExcelVbaSignature(Part); - } - return _signature; - } - } - ExcelVbaProtection _protection=null; - /// - /// VBA protection - /// - public ExcelVbaProtection Protection - { - get - { - if (_protection == null) - { - _protection = new ExcelVbaProtection(this); - } - return _protection; - } - } - #endregion -#if !MONO - #region Read Project - private void GetProject() - { - - var stream = Part.GetStream(); - byte[] vba; - vba = new byte[stream.Length]; - stream.Read(vba, 0, (int)stream.Length); - Document = new CompoundDocument(vba); - - ReadDirStream(); - ProjectStreamText = Encoding.GetEncoding(CodePage).GetString(Document.Storage.DataStreams["PROJECT"]); - ReadModules(); - ReadProjectProperties(); - } - private void ReadModules() - { - foreach (var modul in Modules) - { - var stream = Document.Storage.SubStorage["VBA"].DataStreams[modul.streamName]; - var byCode = CompoundDocument.DecompressPart(stream, (int)modul.ModuleOffset); - string code = Encoding.GetEncoding(CodePage).GetString(byCode); - int pos=0; - while(pos+90) - { - lineSplit = code.Substring(pos + 9, linePos - pos - 9).Split('='); - } - else - { - lineSplit=code.Substring(pos+9).Split(new char[]{'='},1); - } - if (lineSplit.Length > 1) - { - lineSplit[1] = lineSplit[1].Trim(); - var attr = - new ExcelVbaModuleAttribute() - { - Name = lineSplit[0].Trim(), - DataType = lineSplit[1].StartsWith("\"") ? eAttributeDataType.String : eAttributeDataType.NonString, - Value = lineSplit[1].StartsWith("\"") ? lineSplit[1].Substring(1, lineSplit[1].Length - 2) : lineSplit[1] - }; - modul.Attributes._list.Add(attr); - } - pos = linePos + 2; - } - modul.Code=code.Substring(pos); - } - } - - private void ReadProjectProperties() - { - _protection = new ExcelVbaProtection(this); - string prevPackage = ""; - var lines = Regex.Split(ProjectStreamText, "\r\n"); - foreach (string line in lines) - { - if (line.StartsWith("[")) - { - - } - else - { - var split = line.Split('='); - if (split.Length > 1 && split[1].Length > 1 && split[1].StartsWith("\"")) //Remove any double qouates - { - split[1] = split[1].Substring(1, split[1].Length - 2); - } - switch (split[0]) - { - case "ID": - ProjectID = split[1]; - break; - case "Document": - string mn = split[1].Substring(0, split[1].IndexOf("/&H")); - Modules[mn].Type = eModuleType.Document; - break; - case "Package": - prevPackage = split[1]; - break; - case "BaseClass": - Modules[split[1]].Type = eModuleType.Designer; - Modules[split[1]].ClassID = prevPackage; - break; - case "Module": - Modules[split[1]].Type = eModuleType.Module; - break; - case "Class": - Modules[split[1]].Type = eModuleType.Class; - break; - case "HelpFile": - case "Name": - case "HelpContextID": - case "Description": - case "VersionCompatible32": - break; - //393222000" - case "CMG": - byte[] cmg = Decrypt(split[1]); - _protection.UserProtected = (cmg[0] & 1) != 0; - _protection.HostProtected = (cmg[0] & 2) != 0; - _protection.VbeProtected = (cmg[0] & 4) != 0; - break; - case "DPB": - byte[] dpb = Decrypt(split[1]); - if (dpb.Length >= 28) - { - byte reserved = dpb[0]; - var flags = new byte[3]; - Array.Copy(dpb, 1, flags, 0, 3); - var keyNoNulls = new byte[4]; - _protection.PasswordKey = new byte[4]; - Array.Copy(dpb, 4, keyNoNulls, 0, 4); - var hashNoNulls = new byte[20]; - _protection.PasswordHash = new byte[20]; - Array.Copy(dpb, 8, hashNoNulls, 0, 20); - //Handle 0x00 bitwise 2.4.4.3 - for (int i = 0; i < 24; i++) - { - int bit = 128 >> (int)((i % 8)); - if (i < 4) - { - if ((int)(flags[0] & bit) == 0) - { - _protection.PasswordKey[i] = 0; - } - else - { - _protection.PasswordKey[i] = keyNoNulls[i]; - } - } - else - { - int flagIndex = (i - i % 8) / 8; - if ((int)(flags[flagIndex] & bit) == 0) - { - _protection.PasswordHash[i - 4] = 0; - } - else - { - _protection.PasswordHash[i - 4] = hashNoNulls[i - 4]; - } - } - } - } - break; - case "GC": - _protection.VisibilityState = Decrypt(split[1])[0] == 0xFF; - - break; - } - } - } - } - - /// - /// 2.4.3.3 Decryption - /// - /// Byte hex string - /// The decrypted value - private byte[] Decrypt(string value) - { - byte[] enc = GetByte(value); - byte[] dec = new byte[(value.Length - 1)]; - byte seed, version, projKey, ignoredLength; - seed = enc[0]; - dec[0] = (byte)(enc[1] ^ seed); - dec[1] = (byte)(enc[2] ^ seed); - for (int i = 2; i < enc.Length - 1; i++) - { - dec[i] = (byte)(enc[i + 1] ^ (enc[i - 1] + dec[i - 1])); - } - version = dec[0]; - projKey = dec[1]; - ignoredLength = (byte)((seed & 6) / 2); - int datalength = BitConverter.ToInt32(dec, ignoredLength + 2); - var data = new byte[datalength]; - Array.Copy(dec, 6 + ignoredLength, data, 0, datalength); - return data; - } - /// - /// 2.4.3.2 Encryption - /// - /// - /// Byte hex string - private string Encrypt(byte[] value) - { - byte[] seed = new byte[1]; - var rn = RandomNumberGenerator.Create(); - rn.GetBytes(seed); - BinaryWriter br = new BinaryWriter(new MemoryStream()); - byte[] enc = new byte[value.Length + 10]; - enc[0] = seed[0]; - enc[1] = (byte)(2 ^ seed[0]); - - byte projKey = 0; - - foreach (var c in ProjectID) - { - projKey += (byte)c; - } - enc[2] = (byte)(projKey ^ seed[0]); - var ignoredLength = (seed[0] & 6) / 2; - for (int i = 0; i < ignoredLength; i++) - { - br.Write(seed[0]); - } - br.Write(value.Length); - br.Write(value); - - int pos = 3; - byte pb = projKey; - foreach (var b in ((MemoryStream)br.BaseStream).ToArray()) - { - enc[pos] = (byte)(b ^ (enc[pos - 2] + pb)); - pos++; - pb = b; - } - - return GetString(enc, pos - 1); - } - private string GetString(byte[] value, int max) - { - string ret = ""; - for (int i = 0; i <= max; i++) - { - if (value[i] < 16) - { - ret += "0" + value[i].ToString("x"); - } - else - { - ret += value[i].ToString("x"); - } - } - return ret.ToUpper(CultureInfo.InvariantCulture); - } - private byte[] GetByte(string value) - { - byte[] ret = new byte[value.Length / 2]; - for (int i = 0; i < ret.Length; i++) - { - ret[i] = byte.Parse(value.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier); - } - return ret; - } - private void ReadDirStream() - { - byte[] dir = CompoundDocument.DecompressPart(Document.Storage.SubStorage["VBA"].DataStreams["dir"]); - MemoryStream ms = new MemoryStream(dir); - BinaryReader br = new BinaryReader(ms); - ExcelVbaReference currentRef = null; - string referenceName = ""; - ExcelVBAModule currentModule = null; - bool terminate = false; - while (br.BaseStream.Position < br.BaseStream.Length && terminate == false) - { - ushort id = br.ReadUInt16(); - uint size = br.ReadUInt32(); - switch (id) - { - case 0x01: - SystemKind = (eSyskind)br.ReadUInt32(); - break; - case 0x02: - Lcid = (int)br.ReadUInt32(); - break; - case 0x03: - CodePage = (int)br.ReadUInt16(); - break; - case 0x04: - Name = GetString(br, size); - break; - case 0x05: - Description = GetUnicodeString(br, size); - break; - case 0x06: - HelpFile1 = GetString(br, size); - break; - case 0x3D: - HelpFile2 = GetString(br, size); - break; - case 0x07: - HelpContextID = (int)br.ReadUInt32(); - break; - case 0x08: - LibFlags = (int)br.ReadUInt32(); - break; - case 0x09: - MajorVersion = (int)br.ReadUInt32(); - MinorVersion = (int)br.ReadUInt16(); - break; - case 0x0C: - Constants = GetUnicodeString(br, size); - break; - case 0x0D: - uint sizeLibID = br.ReadUInt32(); - var regRef = new ExcelVbaReference(); - regRef.Name = referenceName; - regRef.ReferenceRecordID = id; - regRef.Libid = GetString(br, sizeLibID); - uint reserved1 = br.ReadUInt32(); - ushort reserved2 = br.ReadUInt16(); - References.Add(regRef); - break; - case 0x0E: - var projRef = new ExcelVbaReferenceProject(); - projRef.ReferenceRecordID = id; - projRef.Name = referenceName; - sizeLibID = br.ReadUInt32(); - projRef.Libid = GetString(br, sizeLibID); - sizeLibID = br.ReadUInt32(); - projRef.LibIdRelative = GetString(br, sizeLibID); - projRef.MajorVersion = br.ReadUInt32(); - projRef.MinorVersion = br.ReadUInt16(); - References.Add(projRef); - break; - case 0x0F: - ushort modualCount = br.ReadUInt16(); - break; - case 0x13: - ushort cookie = br.ReadUInt16(); - break; - case 0x14: - LcidInvoke = (int)br.ReadUInt32(); - break; - case 0x16: - referenceName = GetUnicodeString(br, size); - break; - case 0x19: - currentModule = new ExcelVBAModule(); - currentModule.Name = GetUnicodeString(br, size); - Modules.Add(currentModule); - break; - case 0x1A: - currentModule.streamName = GetUnicodeString(br, size); - break; - case 0x1C: - currentModule.Description = GetUnicodeString(br, size); - break; - case 0x1E: - currentModule.HelpContext = (int)br.ReadUInt32(); - break; - case 0x21: - case 0x22: - break; - case 0x2B: //Modul Terminator - break; - case 0x2C: - currentModule.Cookie = br.ReadUInt16(); - break; - case 0x31: - currentModule.ModuleOffset = br.ReadUInt32(); - break; - case 0x10: - terminate = true; - break; - case 0x30: - var extRef = (ExcelVbaReferenceControl)currentRef; - var sizeExt = br.ReadUInt32(); - extRef.LibIdExternal = GetString(br, sizeExt); - - uint reserved4 = br.ReadUInt32(); - ushort reserved5 = br.ReadUInt16(); - extRef.OriginalTypeLib = new Guid(br.ReadBytes(16)); - extRef.Cookie = br.ReadUInt32(); - break; - case 0x33: - currentRef = new ExcelVbaReferenceControl(); - currentRef.ReferenceRecordID = id; - currentRef.Name = referenceName; - currentRef.Libid = GetString(br, size); - References.Add(currentRef); - break; - case 0x2F: - var contrRef = (ExcelVbaReferenceControl)currentRef; - contrRef.ReferenceRecordID = id; - - var sizeTwiddled = br.ReadUInt32(); - contrRef.LibIdTwiddled = GetString(br, sizeTwiddled); - var r1 = br.ReadUInt32(); - var r2 = br.ReadUInt16(); - - break; - case 0x25: - currentModule.ReadOnly = true; - break; - case 0x28: - currentModule.Private = true; - break; - default: - break; - } - } - } - #endregion - - #region Save Project - internal void Save() - { - if (Validate()) - { - CompoundDocument doc = new CompoundDocument(); - doc.Storage = new CompoundDocument.StoragePart(); - var store = new CompoundDocument.StoragePart(); - doc.Storage.SubStorage.Add("VBA", store); - - store.DataStreams.Add("_VBA_PROJECT", CreateVBAProjectStream()); - store.DataStreams.Add("dir", CreateDirStream()); - foreach (var module in Modules) - { - store.DataStreams.Add(module.Name, CompoundDocument.CompressPart(Encoding.GetEncoding(CodePage).GetBytes(module.Attributes.GetAttributeText() + module.Code))); - } - - //Copy streams from the template, if used. - if (Document != null) - { - foreach (var ss in Document.Storage.SubStorage) - { - if (ss.Key != "VBA") - { - doc.Storage.SubStorage.Add(ss.Key, ss.Value); - } - } - foreach (var s in Document.Storage.DataStreams) - { - if (s.Key != "dir" && s.Key != "PROJECT" && s.Key != "PROJECTwm") - { - doc.Storage.DataStreams.Add(s.Key, s.Value); - } - } - } - - doc.Storage.DataStreams.Add("PROJECT", CreateProjectStream()); - doc.Storage.DataStreams.Add("PROJECTwm", CreateProjectwmStream()); - - if (Part == null) - { - Uri = new Uri(PartUri, UriKind.Relative); - Part = _pck.CreatePart(Uri, ExcelPackage.schemaVBA); - var rel = _wb.Part.CreateRelationship(Uri, Packaging.TargetMode.Internal, schemaRelVba); - } - var vbaBuffer=doc.Save(); - var st = Part.GetStream(FileMode.Create); - st.Write(vbaBuffer, 0, vbaBuffer.Length); - st.Flush(); - //Save the digital signture - Signature.Save(this); - } - } - - private bool Validate() - { - Description = Description ?? ""; - HelpFile1 = HelpFile1 ?? ""; - HelpFile2 = HelpFile2 ?? ""; - Constants = Constants ?? ""; - return true; - } - - /// - /// MS-OVBA 2.3.4.1 - /// - /// - private byte[] CreateVBAProjectStream() - { - BinaryWriter bw = new BinaryWriter(new MemoryStream()); - bw.Write((ushort)0x61CC); //Reserved1 - bw.Write((ushort)0xFFFF); //Version - bw.Write((byte)0x0); //Reserved3 - bw.Write((ushort)0x0); //Reserved4 - return ((MemoryStream)bw.BaseStream).ToArray(); - } - /// - /// MS-OVBA 2.3.4.1 - /// - /// - private byte[] CreateDirStream() - { - BinaryWriter bw = new BinaryWriter(new MemoryStream()); - - /****** PROJECTINFORMATION Record ******/ - bw.Write((ushort)1); //ID - bw.Write((uint)4); //Size - bw.Write((uint)SystemKind); //SysKind - - bw.Write((ushort)2); //ID - bw.Write((uint)4); //Size - bw.Write((uint)Lcid); //Lcid - - bw.Write((ushort)0x14); //ID - bw.Write((uint)4); //Size - bw.Write((uint)LcidInvoke); //Lcid Invoke - - bw.Write((ushort)3); //ID - bw.Write((uint)2); //Size - bw.Write((ushort)CodePage); //Codepage - - //ProjectName - bw.Write((ushort)4); //ID - bw.Write((uint)Name.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Name)); //Project Name - - //Description - bw.Write((ushort)5); //ID - bw.Write((uint)Description.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Description)); //Project Name - bw.Write((ushort)0x40); //ID - bw.Write((uint)Description.Length*2); //Size - bw.Write(Encoding.Unicode.GetBytes(Description)); //Project Description - - //Helpfiles - bw.Write((ushort)6); //ID - bw.Write((uint)HelpFile1.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile1)); //HelpFile1 - bw.Write((ushort)0x3D); //ID - bw.Write((uint)HelpFile2.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile2)); //HelpFile2 - - //Help context id - bw.Write((ushort)7); //ID - bw.Write((uint)4); //Size - bw.Write((uint)HelpContextID); //Help context id - - //Libflags - bw.Write((ushort)8); //ID - bw.Write((uint)4); //Size - bw.Write((uint)0); //Help context id - - //Vba Version - bw.Write((ushort)9); //ID - bw.Write((uint)4); //Reserved - bw.Write((uint)MajorVersion); //Reserved - bw.Write((ushort)MinorVersion); //Help context id - - //Constants - bw.Write((ushort)0x0C); //ID - bw.Write((uint)Constants.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Constants)); //Help context id - bw.Write((ushort)0x3C); //ID - bw.Write((uint)Constants.Length/2); //Size - bw.Write(Encoding.Unicode.GetBytes(Constants)); //HelpFile2 - - /****** PROJECTREFERENCES Record ******/ - foreach (var reference in References) - { - WriteNameReference(bw, reference); - - if (reference.ReferenceRecordID == 0x2F) - { - WriteControlReference(bw, reference); - } - else if (reference.ReferenceRecordID == 0x33) - { - WriteOrginalReference(bw, reference); - } - else if (reference.ReferenceRecordID == 0x0D) - { - WriteRegisteredReference(bw, reference); - } - else if (reference.ReferenceRecordID == 0x0E) - { - WriteProjectReference(bw, reference); - } - } - - bw.Write((ushort)0x0F); - bw.Write((uint)0x02); - bw.Write((ushort)Modules.Count); - bw.Write((ushort)0x13); - bw.Write((uint)0x02); - bw.Write((ushort)0xFFFF); - - foreach (var module in Modules) - { - WriteModuleRecord(bw, module); - } - bw.Write((ushort)0x10); //Terminator - bw.Write((uint)0); - - return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray()); - } - - private void WriteModuleRecord(BinaryWriter bw, ExcelVBAModule module) - { - bw.Write((ushort)0x19); - bw.Write((uint)module.Name.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Name - - bw.Write((ushort)0x47); - bw.Write((uint)module.Name.Length*2); - bw.Write(Encoding.Unicode.GetBytes(module.Name)); //Name - - bw.Write((ushort)0x1A); - bw.Write((uint)module.Name.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Stream Name - - bw.Write((ushort)0x32); - bw.Write((uint)module.Name.Length*2); - bw.Write(Encoding.Unicode.GetBytes(module.Name)); //Stream Name - - module.Description = module.Description ?? ""; - bw.Write((ushort)0x1C); - bw.Write((uint)module.Description.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Description)); //Description - - bw.Write((ushort)0x48); - bw.Write((uint)module.Description.Length*2); - bw.Write(Encoding.Unicode.GetBytes(module.Description)); //Description - - bw.Write((ushort)0x31); - bw.Write((uint)4); - bw.Write((uint)0); //Module Stream Offset (No PerformanceCache) - - bw.Write((ushort)0x1E); - bw.Write((uint)4); - bw.Write((uint)module.HelpContext); //Help context ID - - bw.Write((ushort)0x2C); - bw.Write((uint)2); - bw.Write((ushort)0xFFFF); //Help context ID - - bw.Write((ushort)(module.Type == eModuleType.Module ? 0x21 : 0x22)); - bw.Write((uint)0); - - if (module.ReadOnly) - { - bw.Write((ushort)0x25); - bw.Write((uint)0); //Readonly - } - - if (module.Private) - { - bw.Write((ushort)0x28); - bw.Write((uint)0); //Private - } - - bw.Write((ushort)0x2B); //Terminator - bw.Write((uint)0); - } - - private void WriteNameReference(BinaryWriter bw, ExcelVbaReference reference) - { - //Name record - bw.Write((ushort)0x16); //ID - bw.Write((uint)reference.Name.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Name)); //HelpFile1 - bw.Write((ushort)0x3E); //ID - bw.Write((uint)reference.Name.Length * 2); //Size - bw.Write(Encoding.Unicode.GetBytes(reference.Name)); //HelpFile2 - } - private void WriteControlReference(BinaryWriter bw, ExcelVbaReference reference) - { - WriteOrginalReference(bw, reference); - - bw.Write((ushort)0x2F); - var controlRef=(ExcelVbaReferenceControl)reference; - bw.Write((uint)(4 + controlRef.LibIdTwiddled.Length + 4 + 2)); // Size of SizeOfLibidTwiddled, LibidTwiddled, Reserved1, and Reserved2. - bw.Write((uint)controlRef.LibIdTwiddled.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdTwiddled)); //LibID - bw.Write((uint)0); //Reserved1 - bw.Write((ushort)0); //Reserved2 - WriteNameReference(bw, reference); //Name record again - bw.Write((ushort)0x30); //Reserved3 - bw.Write((uint)(4 + controlRef.LibIdExternal.Length + 4 + 2 + 16 + 4)); //Size of SizeOfLibidExtended, LibidExtended, Reserved4, Reserved5, OriginalTypeLib, and Cookie - bw.Write((uint)controlRef.LibIdExternal.Length); //Size - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdExternal)); //LibID - bw.Write((uint)0); //Reserved4 - bw.Write((ushort)0); //Reserved5 - bw.Write(controlRef.OriginalTypeLib.ToByteArray()); - bw.Write((uint)controlRef.Cookie); //Cookie - } - - private void WriteOrginalReference(BinaryWriter bw, ExcelVbaReference reference) - { - bw.Write((ushort)0x33); - bw.Write((uint)reference.Libid.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid)); //LibID - } - private void WriteProjectReference(BinaryWriter bw, ExcelVbaReference reference) - { - bw.Write((ushort)0x0E); - var projRef = (ExcelVbaReferenceProject)reference; - bw.Write((uint)(4 + projRef.Libid.Length + 4 + projRef.LibIdRelative.Length+4+2)); - bw.Write((uint)projRef.Libid.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.Libid)); //LibAbsolute - bw.Write((uint)projRef.LibIdRelative.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.LibIdRelative)); //LibIdRelative - bw.Write(projRef.MajorVersion); - bw.Write(projRef.MinorVersion); - } - - private void WriteRegisteredReference(BinaryWriter bw, ExcelVbaReference reference) - { - bw.Write((ushort)0x0D); - bw.Write((uint)(4+reference.Libid.Length+4+2)); - bw.Write((uint)reference.Libid.Length); - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid)); //LibID - bw.Write((uint)0); //Reserved1 - bw.Write((ushort)0); //Reserved2 - } - - private byte[] CreateProjectwmStream() - { - BinaryWriter bw = new BinaryWriter(new MemoryStream()); - - foreach (var module in Modules) - { - bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Name - bw.Write((byte)0); //Null - bw.Write(Encoding.Unicode.GetBytes(module.Name)); //Name - bw.Write((ushort)0); //Null - } - bw.Write((ushort)0); //Null - return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray()); - } - private byte[] CreateProjectStream() - { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("ID=\"{0}\"\r\n", ProjectID); - foreach(var module in Modules) - { - if (module.Type == eModuleType.Document) - { - sb.AppendFormat("Document={0}/&H00000000\r\n", module.Name); - } - else if (module.Type == eModuleType.Module) - { - sb.AppendFormat("Module={0}\r\n", module.Name); - } - else if (module.Type == eModuleType.Class) - { - sb.AppendFormat("Class={0}\r\n", module.Name); - } - else - { - //Designer - sb.AppendFormat("Package={0}\r\n", module.ClassID); - sb.AppendFormat("BaseClass={0}\r\n", module.Name); - } - } - if (HelpFile1 != "") - { - sb.AppendFormat("HelpFile={0}\r\n", HelpFile1); - } - sb.AppendFormat("Name=\"{0}\"\r\n", Name); - sb.AppendFormat("HelpContextID={0}\r\n", HelpContextID); - - if (!string.IsNullOrEmpty(Description)) - { - sb.AppendFormat("Description=\"{0}\"\r\n", Description); - } - sb.AppendFormat("VersionCompatible32=\"393222000\"\r\n"); - - sb.AppendFormat("CMG=\"{0}\"\r\n", WriteProtectionStat()); - sb.AppendFormat("DPB=\"{0}\"\r\n", WritePassword()); - sb.AppendFormat("GC=\"{0}\"\r\n\r\n", WriteVisibilityState()); - - sb.Append("[Host Extender Info]\r\n"); - sb.Append("&H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000\r\n"); - sb.Append("\r\n"); - sb.Append("[Workspace]\r\n"); - foreach(var module in Modules) - { - sb.AppendFormat("{0}=0, 0, 0, 0, C \r\n",module.Name); - } - string s = sb.ToString(); - return Encoding.GetEncoding(CodePage).GetBytes(s); - } - private string WriteProtectionStat() - { - int stat=(_protection.UserProtected ? 1:0) | - (_protection.HostProtected ? 2:0) | - (_protection.VbeProtected ? 4:0); - - return Encrypt(BitConverter.GetBytes(stat)); - } - private string WritePassword() - { - byte[] nullBits=new byte[3]; - byte[] nullKey = new byte[4]; - byte[] nullHash = new byte[20]; - if (Protection.PasswordKey == null) - { - return Encrypt(new byte[] { 0 }); - } - else - { - Array.Copy(Protection.PasswordKey, nullKey, 4); - Array.Copy(Protection.PasswordHash, nullHash, 20); - - //Set Null bits - for (int i = 0; i < 24; i++) - { - byte bit = (byte)(128 >> (int)((i % 8))); - if (i < 4) - { - if (nullKey[i] == 0) - { - nullKey[i] = 1; - } - else - { - nullBits[0] |= bit; - } - } - else - { - if (nullHash[i - 4] == 0) - { - nullHash[i - 4] = 1; - } - else - { - int byteIndex = (i - i % 8) / 8; - nullBits[byteIndex] |= bit; - } - } - } - //Write the Password Hash Data Structure (2.4.4.1) - BinaryWriter bw = new BinaryWriter(new MemoryStream()); - bw.Write((byte)0xFF); - bw.Write(nullBits); - bw.Write(nullKey); - bw.Write(nullHash); - bw.Write((byte)0); - return Encrypt(((MemoryStream)bw.BaseStream).ToArray()); - } - } - private string WriteVisibilityState() - { - return Encrypt(new byte[] { (byte)(Protection.VisibilityState ? 0xFF : 0) }); - } - #endregion - private string GetString(BinaryReader br, uint size) - { - return GetString(br, size, System.Text.Encoding.GetEncoding(CodePage)); - } - private string GetString(BinaryReader br, uint size, Encoding enc) - { - if (size > 0) - { - byte[] byteTemp = new byte[size]; - byteTemp = br.ReadBytes((int)size); - return enc.GetString(byteTemp); - } - else - { - return ""; - } - } - private string GetUnicodeString(BinaryReader br, uint size) - { - string s = GetString(br, size); - int reserved = br.ReadUInt16(); - uint sizeUC = br.ReadUInt32(); - string sUC = GetString(br, sizeUC, System.Text.Encoding.Unicode); - return sUC.Length == 0 ? s : sUC; - } - internal CompoundDocument Document { get; set; } -#endif - internal Packaging.ZipPackagePart Part { get; set; } - internal Uri Uri { get; private set; } -#if !MONO - /// - /// Create a new VBA Project - /// - internal void Create() - { - if(Lcid>0) - { - throw (new InvalidOperationException("Package already contains a VBAProject")); - } - ProjectID = "{5DD90D76-4904-47A2-AF0D-D69B4673604E}"; - Name = "VBAProject"; - SystemKind = eSyskind.Win32; //Default - Lcid = 1033; //English - United States - LcidInvoke = 1033; //English - United States - CodePage = Encoding.Default.CodePage; - MajorVersion = 1361024421; - MinorVersion = 6; - HelpContextID = 0; - Modules.Add(new ExcelVBAModule(_wb.CodeNameChange) { Name = "ThisWorkbook", Code = "", Attributes=GetDocumentAttributes("ThisWorkbook", "0{00020819-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 }); - foreach (var sheet in _wb.Worksheets) - { - var name = GetModuleNameFromWorksheet(sheet); - if (!Modules.Exists(name)) - { - Modules.Add(new ExcelVBAModule(sheet.CodeNameChange) { Name = name, Code = "", Attributes = GetDocumentAttributes(sheet.Name, "0{00020820-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 }); - } - } - _protection = new ExcelVbaProtection(this) { UserProtected = false, HostProtected = false, VbeProtected = false, VisibilityState = true }; - } - - internal string GetModuleNameFromWorksheet(ExcelWorksheet sheet) - { - var name = sheet.Name; - if (name.Any(c => c > 255) || this.Modules[name] != null) - { - int i = sheet.PositionID; - name = "Sheet" + i.ToString(); - while (this.Modules[name] != null) - { - name = "Sheet" + (++i).ToString(); ; - } - } - return name; - } - internal ExcelVbaModuleAttributesCollection GetDocumentAttributes(string name, string clsid) - { - var attr = new ExcelVbaModuleAttributesCollection(); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = name, DataType = eAttributeDataType.String }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = clsid, DataType = eAttributeDataType.String }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "True", DataType = eAttributeDataType.NonString }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = "False", DataType = eAttributeDataType.NonString }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString }); - attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "True", DataType = eAttributeDataType.NonString }); - - return attr; - } - - - //internal string GetBlankDocumentModule(string name, string clsid) - //{ - // string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name); - // ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", clsid); //Microsoft.Office.Interop.Excel.WorksheetClass - // ret += "Attribute VB_GlobalNameSpace = False\r\n"; - // ret += "Attribute VB_Creatable = False\r\n"; - // ret += "Attribute VB_PredeclaredId = True\r\n"; - // ret += "Attribute VB_Exposed = True\r\n"; - // ret += "Attribute VB_TemplateDerived = False\r\n"; - // ret += "Attribute VB_Customizable = True"; - // return ret; - //} - //internal string GetBlankModule(string name) - //{ - // return string.Format("Attribute VB_Name = \"{0}\"\r\n", name); - //} - //internal string GetBlankClassModule(string name, bool exposed) - //{ - // string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name); - // ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}"); - // ret += "Attribute VB_GlobalNameSpace = False\r\n"; - // ret += "Attribute VB_Creatable = False\r\n"; - // ret += "Attribute VB_PredeclaredId = False\r\n"; - // ret += string.Format("Attribute VB_Exposed = {0}\r\n", exposed ? "True" : "False"); - // ret += "Attribute VB_TemplateDerived = False\r\n"; - // ret += "Attribute VB_Customizable = False\r\n"; - // return ret; - //} -#endif - /// - /// Remove the project from the package - /// - public void Remove() - { - if (Part == null) return; - - foreach (var rel in Part.GetRelationships()) - { - _pck.DeleteRelationship(rel.Id); - } - if (_pck.PartExists(Uri)) - { - _pck.DeletePart(Uri); - } - Part = null; - Modules.Clear(); - References.Clear(); - Lcid = 0; - LcidInvoke = 0; - CodePage = 0; - MajorVersion = 0; - MinorVersion = 0; - HelpContextID = 0; - } - public override string ToString() - { - return Name; - } - } -} Index: VBA/ExcelVBAReference.cs =================================================================== --- VBA/ExcelVBAReference.cs (Revision 12462) +++ VBA/ExcelVBAReference.cs (Arbeitskopie) @@ -1,129 +0,0 @@ -/******************************************************************************* - * You may amend and distribute as you like, but don't remove this header! - * - * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. - * See http://www.codeplex.com/EPPlus for details. - * - * Copyright (C) 2011 Jan Källman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php - * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html - * - * All code and executables are provided "as is" with no warranty either express or implied. - * The author accepts no liability for any damage or loss of business that this product may cause. - * - * Code change notes: - * - * Author Change Date - ******************************************************************************* - * Jan Källman Added 26-MAR-2012 - *******************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace OfficeOpenXml.VBA -{ - /// - /// A VBA reference - /// - public class ExcelVbaReference - { - /// - /// Constructor. - /// Defaults ReferenceRecordID to 0xD - /// - public ExcelVbaReference() - { - ReferenceRecordID = 0xD; - } - /// - /// The reference record ID. See MS-OVBA documentation for more info. - /// - public int ReferenceRecordID { get; internal set; } - /// - /// The name of the reference - /// - public string Name { get; set; } - /// - /// LibID - /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES - /// - public string Libid { get; set; } - /// - /// A string representation of the object (the Name) - /// - /// - public override string ToString() - { - return Name; - } - } - /// - /// A reference to a twiddled type library - /// - public class ExcelVbaReferenceControl : ExcelVbaReference - { - /// - /// Constructor. - /// Sets ReferenceRecordID to 0x2F - /// - public ExcelVbaReferenceControl() - { - ReferenceRecordID = 0x2F; - } - /// - /// LibIdExternal - /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES - /// - public string LibIdExternal { get; set; } - /// - /// LibIdTwiddled - /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES - /// - public string LibIdTwiddled { get; set; } - /// - /// A GUID that specifies the Automation type library the extended type library was generated from. - /// - public Guid OriginalTypeLib { get; set; } - internal uint Cookie { get; set; } - } - /// - /// A reference to an external VBA project - /// - public class ExcelVbaReferenceProject : ExcelVbaReference - { - /// - /// Constructor. - /// Sets ReferenceRecordID to 0x0E - /// - public ExcelVbaReferenceProject() - { - ReferenceRecordID = 0x0E; - } - /// - /// LibIdRelative - /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES - /// - public string LibIdRelative { get; set; } - /// - /// Major version of the referenced VBA project - /// - public uint MajorVersion { get; set; } - /// - /// Minor version of the referenced VBA project - /// - public ushort MinorVersion { get; set; } - } -} Index: VBA/ExcelVBASignature.cs =================================================================== --- VBA/ExcelVBASignature.cs (Revision 12462) +++ VBA/ExcelVBASignature.cs (Arbeitskopie) @@ -1,384 +0,0 @@ -/******************************************************************************* - * You may amend and distribute as you like, but don't remove this header! - * - * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. - * See http://www.codeplex.com/EPPlus for details. - * - * Copyright (C) 2011 Jan Källman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php - * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html - * - * All code and executables are provided "as is" with no warranty either express or implied. - * The author accepts no liability for any damage or loss of business that this product may cause. - * - * Code change notes: - * - * Author Change Date - ******************************************************************************* - * Jan Källman Added 26-MAR-2012 - *******************************************************************************/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Security.Cryptography.X509Certificates; -using System.Security.Cryptography.Pkcs; -using OfficeOpenXml.Utils; -using System.IO; - -namespace OfficeOpenXml.VBA -{ - /// - /// The code signature properties of the project - /// - public class ExcelVbaSignature - { - const string schemaRelVbaSignature = "http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature"; - Packaging.ZipPackagePart _vbaPart = null; - internal ExcelVbaSignature(Packaging.ZipPackagePart vbaPart) - { - _vbaPart = vbaPart; - GetSignature(); - } - private void GetSignature() - { - if (_vbaPart == null) return; - var rel = _vbaPart.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault(); - if (rel != null) - { - Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri); - Part = _vbaPart.Package.GetPart(Uri); - - var stream = Part.GetStream(); - BinaryReader br = new BinaryReader(stream); - uint cbSignature = br.ReadUInt32(); - uint signatureOffset = br.ReadUInt32(); //44 ?? - uint cbSigningCertStore = br.ReadUInt32(); - uint certStoreOffset = br.ReadUInt32(); - uint cbProjectName = br.ReadUInt32(); - uint projectNameOffset = br.ReadUInt32(); - uint fTimestamp = br.ReadUInt32(); - uint cbTimestampUrl = br.ReadUInt32(); - uint timestampUrlOffset = br.ReadUInt32(); - byte[] signature = br.ReadBytes((int)cbSignature); - uint version = br.ReadUInt32(); - uint fileType = br.ReadUInt32(); - - uint id = br.ReadUInt32(); - while (id != 0) - { - uint encodingType = br.ReadUInt32(); - uint length = br.ReadUInt32(); - if (length > 0) - { - byte[] value = br.ReadBytes((int)length); - switch (id) - { - //Add property values here... - case 0x20: - Certificate = new X509Certificate2(value); - break; - default: - break; - } - } - id = br.ReadUInt32(); - } - uint endel1 = br.ReadUInt32(); //0 - uint endel2 = br.ReadUInt32(); //0 - ushort rgchProjectNameBuffer = br.ReadUInt16(); - ushort rgchTimestampBuffer = br.ReadUInt16(); - Verifier = new SignedCms(); - Verifier.Decode(signature); - } - else - { - Certificate = null; - Verifier = null; - } - } - //Create Oid from a bytearray - //private string ReadHash(byte[] content) - //{ - // StringBuilder builder = new StringBuilder(); - // int offset = 0x6; - // if (0 < (content.Length)) - // { - // byte num = content[offset]; - // byte num2 = (byte)(num / 40); - // builder.Append(num2.ToString(null, null)); - // builder.Append("."); - // num2 = (byte)(num % 40); - // builder.Append(num2.ToString(null, null)); - // ulong num3 = 0L; - // for (int i = offset + 1; i < content.Length; i++) - // { - // num2 = content[i]; - // num3 = (ulong)(ulong)(num3 << 7) + ((byte)(num2 & 0x7f)); - // if ((num2 & 0x80) == 0) - // { - // builder.Append("."); - // builder.Append(num3.ToString(null, null)); - // num3 = 0L; - // } - // //1.2.840.113549.2.5 - // } - // } - - - // string oId = builder.ToString(); - - // return oId; - //} - internal void Save(ExcelVbaProject proj) - { - if (Certificate == null) - { - return; - } - - if (Certificate.HasPrivateKey==false) //No signature. Remove any Signature part - { - var storeCert = GetCertFromStore(StoreLocation.CurrentUser); - if (storeCert == null) - { - storeCert = GetCertFromStore(StoreLocation.LocalMachine); - } - if (storeCert != null && storeCert.HasPrivateKey == true) - { - Certificate = storeCert; - } - else - { - foreach (var r in Part.GetRelationships()) - { - Part.DeleteRelationship(r.Id); - } - Part.Package.DeletePart(Part.Uri); - return; - } - } - var ms = new MemoryStream(); - var bw = new BinaryWriter(ms); - - byte[] certStore = GetCertStore(); - - byte[] cert = SignProject(proj); - bw.Write((uint)cert.Length); - bw.Write((uint)44); //?? 36 ref inside cert ?? - bw.Write((uint)certStore.Length); //cbSigningCertStore - bw.Write((uint)(cert.Length + 44)); //certStoreOffset - bw.Write((uint)0); //cbProjectName - bw.Write((uint)(cert.Length + certStore.Length + 44)); //projectNameOffset - bw.Write((uint)0); //fTimestamp - bw.Write((uint)0); //cbTimestampUrl - bw.Write((uint)(cert.Length + certStore.Length + 44 + 2)); //timestampUrlOffset - bw.Write(cert); - bw.Write(certStore); - bw.Write((ushort)0);//rgchProjectNameBuffer - bw.Write((ushort)0);//rgchTimestampBuffer - bw.Write((ushort)0); - bw.Flush(); - - var rel = proj.Part.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault(); - if (Part == null) - { - - if (rel != null) - { - Uri = rel.TargetUri; - Part = proj._pck.GetPart(rel.TargetUri); - } - else - { - Uri = new Uri("/xl/vbaProjectSignature.bin", UriKind.Relative); - Part = proj._pck.CreatePart(Uri, ExcelPackage.schemaVBASignature); - } - } - if (rel == null) - { - proj.Part.CreateRelationship(UriHelper.ResolvePartUri(proj.Uri, Uri), Packaging.TargetMode.Internal, schemaRelVbaSignature); - } - var b = ms.ToArray(); - Part.GetStream(FileMode.Create).Write(b, 0, b.Length); - } - - private X509Certificate2 GetCertFromStore(StoreLocation loc) - { - try - { - X509Store store = new X509Store(loc); - store.Open(OpenFlags.ReadOnly); - try - { - var storeCert = store.Certificates.Find( - X509FindType.FindByThumbprint, - Certificate.Thumbprint, - true - ).OfType().FirstOrDefault(); - return storeCert; - } - finally - { - store.Close(); - } - } - catch - { - return null; - } - } - - private byte[] GetCertStore() - { - var ms = new MemoryStream(); - var bw = new BinaryWriter(ms); - - bw.Write((uint)0); //Version - bw.Write((uint)0x54524543); //fileType - - //SerializedCertificateEntry - var certData = Certificate.RawData; - bw.Write((uint)0x20); - bw.Write((uint)1); - bw.Write((uint)certData.Length); - bw.Write(certData); - - //EndElementMarkerEntry - bw.Write((uint)0); - bw.Write((ulong)0); - - bw.Flush(); - return ms.ToArray(); - } - - private void WriteProp(BinaryWriter bw, int id, byte[] data) - { - bw.Write((uint)id); - bw.Write((uint)1); - bw.Write((uint)data.Length); - bw.Write(data); - } - internal byte[] SignProject(ExcelVbaProject proj) - { - if (!Certificate.HasPrivateKey) - { - //throw (new InvalidOperationException("The certificate doesn't have a private key")); - Certificate = null; - return null; - } - var hash = GetContentHash(proj); - - BinaryWriter bw = new BinaryWriter(new MemoryStream()); - bw.Write((byte)0x30); //Constructed Type - bw.Write((byte)0x32); //Total length - bw.Write((byte)0x30); //Constructed Type - bw.Write((byte)0x0E); //Length SpcIndirectDataContent - bw.Write((byte)0x06); //Oid Tag Indentifier - bw.Write((byte)0x0A); //Lenght OId - 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.29 - bw.Write((byte)0x04); //Octet String Tag Identifier - bw.Write((byte)0x00); //Zero length - - bw.Write((byte)0x30); //Constructed Type (DigestInfo) - bw.Write((byte)0x20); //Length DigestInfo - bw.Write((byte)0x30); //Constructed Type (Algorithm) - bw.Write((byte)0x0C); //length AlgorithmIdentifier - bw.Write((byte)0x06); //Oid Tag Indentifier - bw.Write((byte)0x08); //Lenght OId - bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5) - bw.Write((byte)0x05); //Null type identifier - bw.Write((byte)0x00); //Null length - bw.Write((byte)0x04); //Octet String Identifier - bw.Write((byte)hash.Length); //Hash length - bw.Write(hash); //Content hash - - ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray()); - contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4"; - Verifier = new SignedCms(contentInfo); - var signer = new CmsSigner(Certificate); - Verifier.ComputeSignature(signer, false); - return Verifier.Encode(); - } - - private byte[] GetContentHash(ExcelVbaProject proj) - { - //MS-OVBA 2.4.2 - var enc = System.Text.Encoding.GetEncoding(proj.CodePage); - BinaryWriter bw = new BinaryWriter(new MemoryStream()); - bw.Write(enc.GetBytes(proj.Name)); - bw.Write(enc.GetBytes(proj.Constants)); - foreach (var reference in proj.References) - { - if (reference.ReferenceRecordID == 0x0D) - { - bw.Write((byte)0x7B); - } - if (reference.ReferenceRecordID == 0x0E) - { - //var r = (ExcelVbaReferenceProject)reference; - //BinaryWriter bwTemp = new BinaryWriter(new MemoryStream()); - //bwTemp.Write((uint)r.Libid.Length); - //bwTemp.Write(enc.GetBytes(r.Libid)); - //bwTemp.Write((uint)r.LibIdRelative.Length); - //bwTemp.Write(enc.GetBytes(r.LibIdRelative)); - //bwTemp.Write(r.MajorVersion); - //bwTemp.Write(r.MinorVersion); - 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. - { - if (b != 0) - { - bw.Write(b); - } - else - { - break; - } - } - } - } - foreach (var module in proj.Modules) - { - var lines = module.Code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); - foreach (var line in lines) - { - if (!line.StartsWith("attribute", true, null)) - { - bw.Write(enc.GetBytes(line)); - } - } - } - var buffer = (bw.BaseStream as MemoryStream).ToArray(); - var hp = System.Security.Cryptography.MD5CryptoServiceProvider.Create(); - return hp.ComputeHash(buffer); - } - /// - /// The certificate to sign the VBA project. - /// - /// This certificate must have a private key. - /// 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). - /// - /// - public X509Certificate2 Certificate { get; set; } - /// - /// The verifier - /// - public SignedCms Verifier { get; internal set; } -#if !MONO - internal CompoundDocument Signature { get; set; } -#endif - internal Packaging.ZipPackagePart Part { get; set; } - internal Uri Uri { get; private set; } - } -}