Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/HeuristicLab.EPPlus-4.0.3/epplus-4.0.3-Mono.patch @ 13371

Last change on this file since 13371 was 12715, checked in by mkommend, 9 years ago

#2341: Reverse merged r12714 because one file change relates to another ticket (#2399).

File size: 92.1 KB
RevLine 
[12464]1Index: ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs
2===================================================================
3--- ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs (Revision 12462)
4+++ ConditionalFormatting/ExcelConditionalFormattingIconDatabarValue.cs (Arbeitskopie)
5@@ -1,358 +0,0 @@
6-/*******************************************************************************
7- * You may amend and distribute as you like, but don't remove this header!
8- *
9- * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
10- * See http://www.codeplex.com/EPPlus for details.
11- *
12- * Copyright (C) 2011  Jan KÀllman
13- *
14- * This library is free software; you can redistribute it and/or
15- * modify it under the terms of the GNU Lesser General Public
16- * License as published by the Free Software Foundation; either
17- * version 2.1 of the License, or (at your option) any later version.
18-
19- * This library is distributed in the hope that it will be useful,
20- * but WITHOUT ANY WARRANTY; without even the implied warranty of
21- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
22- * See the GNU Lesser General Public License for more details.
23- *
24- * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
25- * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
26- *
27- * All code and executables are provided "as is" with no warranty either express or implied.
28- * The author accepts no liability for any damage or loss of business that this product may cause.
29- *
30- * Code change notes:
31- *
32- * Author              Change            Date
33- * ******************************************************************************
34- * Eyal Seagull        Added             2012-04-03
35- *******************************************************************************/
36-using System;
37-using System.Collections.Generic;
38-using System.Linq;
39-using System.Text;
40-using System.Drawing;
41-using System.Xml;
42-using OfficeOpenXml.Utils;
43-using System.Text.RegularExpressions;
44-using System.Globalization;
45-using System.Security;
46-
47-namespace OfficeOpenXml.ConditionalFormatting
48-{
49- /// <summary>
50- /// 18.3.1.11 cfvo (Conditional Format Value Object)
51- /// Describes the values of the interpolation points in a gradient scale.
52- /// </summary>
53- public class ExcelConditionalFormattingIconDataBarValue
54-   : XmlHelper
55- {
56-   /****************************************************************************************/
57-
58-   #region Private Properties
59-   private eExcelConditionalFormattingRuleType _ruleType;
60-   private ExcelWorksheet _worksheet;
61-   #endregion Private Properties
62-
63-   /****************************************************************************************/
64-
65-   #region Constructors
66-    /// <summary>
67-    /// Initialize the cfvo (§18.3.1.11) node
68-    /// </summary>
69-    /// <param name="type"></param>
70-    /// <param name="value"></param>
71-    /// <param name="formula"></param>
72-    /// <param name="ruleType"></param>
73-    /// <param name="address"></param>
74-    /// <param name="priority"></param>
75-    /// <param name="worksheet"></param>
76-    /// <param name="itemElementNode">The cfvo (§18.3.1.11) node parent. Can be any of the following:
77-    /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49)</param>
78-    /// <param name="namespaceManager"></param>
79-   internal ExcelConditionalFormattingIconDataBarValue(
80-     eExcelConditionalFormattingValueObjectType type,
81-     double value,
82-     string formula,
83-     eExcelConditionalFormattingRuleType ruleType,
84-            ExcelAddress address,
85-            int priority,
86-     ExcelWorksheet worksheet,
87-     XmlNode itemElementNode,
88-     XmlNamespaceManager namespaceManager)
89-     : this(
90-            ruleType,
91-            address,
92-            worksheet,
93-            itemElementNode,
94-     namespaceManager)
95-   {
96-     Require.Argument(priority).IsInRange(1, int.MaxValue, "priority");
97-
98-            // Check if the parent does not exists
99-     if (itemElementNode == null)
100-     {
101-       // Get the parent node path by the rule type
102-       string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType(
103-         ruleType);
104-
105-       // Check for en error (rule type does not have <cfvo>)
106-       if (parentNodePath == string.Empty)
107-       {
108-         throw new Exception(
109-           ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);
110-       }
111-
112-       // Point to the <cfvo> parent node
113-        itemElementNode = _worksheet.WorksheetXml.SelectSingleNode(
114-         string.Format(
115-           "//{0}[{1}='{2}']/{3}[{4}='{5}']/{6}",
116-         // {0}
117-           ExcelConditionalFormattingConstants.Paths.ConditionalFormatting,
118-         // {1}
119-           ExcelConditionalFormattingConstants.Paths.SqrefAttribute,
120-         // {2}
121-           address.Address,
122-         // {3}
123-           ExcelConditionalFormattingConstants.Paths.CfRule,
124-         // {4}
125-           ExcelConditionalFormattingConstants.Paths.PriorityAttribute,
126-         // {5}
127-           priority,
128-         // {6}
129-           parentNodePath),
130-         _worksheet.NameSpaceManager);
131-
132-       // Check for en error (rule type does not have <cfvo>)
133-                if (itemElementNode == null)
134-       {
135-         throw new Exception(
136-           ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);
137-       }
138-     }
139-
140-            TopNode = itemElementNode;
141-
142-     // Save the attributes
143-     RuleType = ruleType;
144-     Type = type;
145-     Value = value;
146-     Formula = formula;
147-   }
148-    /// <summary>
149-    /// Initialize the cfvo (§18.3.1.11) node
150-    /// </summary>
151-    /// <param name="ruleType"></param>
152-    /// <param name="address"></param>
153-    /// <param name="worksheet"></param>
154-    /// <param name="itemElementNode">The cfvo (§18.3.1.11) node parent. Can be any of the following:
155-    /// colorScale (§18.3.1.16); dataBar (§18.3.1.28); iconSet (§18.3.1.49)</param>
156-    /// <param name="namespaceManager"></param>
157-        internal ExcelConditionalFormattingIconDataBarValue(
158-            eExcelConditionalFormattingRuleType ruleType,
159-            ExcelAddress address,
160-            ExcelWorksheet worksheet,
161-            XmlNode itemElementNode,
162-            XmlNamespaceManager namespaceManager)
163-            : base(
164-                namespaceManager,
165-                itemElementNode)
166-        {
167-            Require.Argument(address).IsNotNull("address");
168-            Require.Argument(worksheet).IsNotNull("worksheet");
169-
170-            // Save the worksheet for private methods to use
171-            _worksheet = worksheet;
172-
173-            // Schema order list
174-            SchemaNodeOrder = new string[]
175-     {
176-                ExcelConditionalFormattingConstants.Nodes.Cfvo,
177-     };
178-
179-            //Check if the parent does not exists
180-            if (itemElementNode == null)
181-            {
182-                // Get the parent node path by the rule type
183-                string parentNodePath = ExcelConditionalFormattingValueObjectType.GetParentPathByRuleType(
184-                    ruleType);
185-
186-                // Check for en error (rule type does not have <cfvo>)
187-                if (parentNodePath == string.Empty)
188-                {
189-                    throw new Exception(
190-                        ExcelConditionalFormattingConstants.Errors.MissingCfvoParentNode);
191-                }
192-            }
193-            RuleType = ruleType;           
194-        }
195-   /// <summary>
196-   /// Initialize the <see cref="ExcelConditionalFormattingColorScaleValue"/>
197-   /// </summary>
198-   /// <param name="type"></param>
199-   /// <param name="value"></param>
200-   /// <param name="formula"></param>
201-   /// <param name="ruleType"></param>
202-   /// <param name="priority"></param>
203-   /// <param name="address"></param>
204-   /// <param name="worksheet"></param>
205-   /// <param name="namespaceManager"></param>
206-   internal ExcelConditionalFormattingIconDataBarValue(
207-     eExcelConditionalFormattingValueObjectType type,
208-     double value,
209-     string formula,
210-     eExcelConditionalFormattingRuleType ruleType,
211-            ExcelAddress address,
212-            int priority,
213-     ExcelWorksheet worksheet,
214-     XmlNamespaceManager namespaceManager)
215-     : this(
216-       type,
217-       value,
218-       formula,
219-       ruleType,
220-                address,
221-                priority,
222-       worksheet,
223-       null,
224-       namespaceManager)
225-   {
226-           
227-   }
228-   /// <summary>
229-   /// Initialize the <see cref="ExcelConditionalFormattingColorScaleValue"/>
230-   /// </summary>
231-   /// <param name="type"></param>
232-   /// <param name="color"></param>
233-   /// <param name="ruleType"></param>
234-   /// <param name="priority"></param>
235-   /// <param name="address"></param>
236-   /// <param name="worksheet"></param>
237-   /// <param name="namespaceManager"></param>
238-   internal ExcelConditionalFormattingIconDataBarValue(
239-     eExcelConditionalFormattingValueObjectType type,
240-     Color color,
241-     eExcelConditionalFormattingRuleType ruleType,
242-            ExcelAddress address,
243-            int priority,
244-     ExcelWorksheet worksheet,
245-     XmlNamespaceManager namespaceManager)
246-     : this(
247-       type,
248-       0,
249-       null,
250-       ruleType,
251-                address,
252-                priority,
253-       worksheet,
254-       null,
255-       namespaceManager)
256-   {
257-   }
258-   #endregion Constructors
259-
260-   /****************************************************************************************/
261-
262-   #region Methods
263-        #endregion
264-
265-        /****************************************************************************************/
266-
267-   #region Exposed Properties
268-
269-   /// <summary>
270-   ///
271-   /// </summary>
272-   internal eExcelConditionalFormattingRuleType RuleType
273-   {
274-     get { return _ruleType; }
275-     set { _ruleType = value; }
276-   }
277-
278-   /// <summary>
279-   ///
280-   /// </summary>
281-   public eExcelConditionalFormattingValueObjectType Type
282-   {
283-     get
284-     {
285-       var typeAttribute = GetXmlNodeString(ExcelConditionalFormattingConstants.Paths.TypeAttribute);
286-
287-       return ExcelConditionalFormattingValueObjectType.GetTypeByAttrbiute(typeAttribute);
288-     }
289-     set
290-     {
291-                if ((_ruleType==eExcelConditionalFormattingRuleType.ThreeIconSet || _ruleType==eExcelConditionalFormattingRuleType.FourIconSet || _ruleType==eExcelConditionalFormattingRuleType.FiveIconSet) &&
292-                    (value == eExcelConditionalFormattingValueObjectType.Min || value == eExcelConditionalFormattingValueObjectType.Max))
293-                {
294-                    throw(new ArgumentException("Value type can't be Min or Max for icon sets"));
295-                }
296-                SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.TypeAttribute, value.ToString().ToLower(CultureInfo.InvariantCulture));               
297-     }
298-   }
299-
300-   /// <summary>
301-   /// Get/Set the 'cfvo' node @val attribute
302-   /// </summary>
303-   public Double Value
304-   {
305-     get
306-     {
307-                if ((Type == eExcelConditionalFormattingValueObjectType.Num)
308-                    || (Type == eExcelConditionalFormattingValueObjectType.Percent)
309-                    || (Type == eExcelConditionalFormattingValueObjectType.Percentile))
310-                {
311-                    return GetXmlNodeDouble(ExcelConditionalFormattingConstants.Paths.ValAttribute);
312-                }
313-                else
314-                {
315-                    return 0;
316-                }
317-            }
318-     set
319-     {
320-       string valueToStore = string.Empty;
321-
322-       // Only some types use the @val attribute
323-       if ((Type == eExcelConditionalFormattingValueObjectType.Num)
324-         || (Type == eExcelConditionalFormattingValueObjectType.Percent)
325-         || (Type == eExcelConditionalFormattingValueObjectType.Percentile))
326-       {
327-         valueToStore = value.ToString(CultureInfo.InvariantCulture);
328-       }
329-
330-                SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute, valueToStore);
331-     }
332-   }
333-
334-   /// <summary>
335-   /// Get/Set the Formula of the Object Value (uses the same attribute as the Value)
336-   /// </summary>
337-   public string Formula
338-   {
339-     get
340-     {
341-       // Return empty if the Object Value type is not Formula
342-       if (Type != eExcelConditionalFormattingValueObjectType.Formula)
343-       {
344-         return string.Empty;
345-       }
346-
347-       // Excel stores the formula in the @val attribute
348-       return GetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute);
349-     }
350-     set
351-     {
352-       // Only store the formula if the Object Value type is Formula
353-       if (Type == eExcelConditionalFormattingValueObjectType.Formula)
354-       {
355-                    SetXmlNodeString(ExcelConditionalFormattingConstants.Paths.ValAttribute, value);
356-       }
357-     }
358-   }
359-   #endregion Exposed Properties
360-
361-   /****************************************************************************************/
362- }
363-}
364\ No newline at end of file
365Index: ExcelWorkbook.cs
366===================================================================
367--- ExcelWorkbook.cs  (Revision 12462)
368+++ ExcelWorkbook.cs  (Arbeitskopie)
369@@ -336,6 +336,9 @@
370                 if (_standardFontWidth == decimal.MinValue || _fontID != Styles.Fonts[0].Id)
371        {
372          var font = Styles.Fonts[0];
373+#if __MonoCS__
374+   _standardFontWidth = (int)(font.Size * (2D / 3D)); //Aprox for Calibri.
375+#else
376                     try
377                     {
378                         //Font f = new Font(font.Name, font.Size);
379@@ -373,6 +376,7 @@
380                     {
381                         _standardFontWidth = (int)(font.Size * (2D / 3D)); //Aprox for Calibri.
382                     }
383+#endif
384        }
385        return _standardFontWidth;
386      }
387Index: VBA/ExcelVBAModuleCollection.cs
388===================================================================
389--- VBA/ExcelVBAModuleCollection.cs (Revision 12462)
390+++ VBA/ExcelVBAModuleCollection.cs (Arbeitskopie)
391@@ -1,210 +0,0 @@
392-/*******************************************************************************
393- * You may amend and distribute as you like, but don't remove this header!
394- *
395- * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
396- * See http://www.codeplex.com/EPPlus for details.
397- *
398- * Copyright (C) 2011  Jan KÀllman
399- *
400- * This library is free software; you can redistribute it and/or
401- * modify it under the terms of the GNU Lesser General Public
402- * License as published by the Free Software Foundation; either
403- * version 2.1 of the License, or (at your option) any later version.
404-
405- * This library is distributed in the hope that it will be useful,
406- * but WITHOUT ANY WARRANTY; without even the implied warranty of
407- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
408- * See the GNU Lesser General Public License for more details.
409- *
410- * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
411- * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
412- *
413- * All code and executables are provided "as is" with no warranty either express or implied.
414- * The author accepts no liability for any damage or loss of business that this product may cause.
415- *
416- * Code change notes:
417- *
418- * Author              Change            Date
419- *******************************************************************************
420- * Jan KÀllman    Added   12-APR-2012
421- *******************************************************************************/
422-using System;
423-using System.Collections.Generic;
424-using System.Linq;
425-using System.Text;
426-
427-namespace OfficeOpenXml.VBA
428-{
429-    /// <summary>
430-    /// Base class for VBA collections
431-    /// </summary>
432-    /// <typeparam name="T"></typeparam>
433-    public class ExcelVBACollectionBase<T> : IEnumerable<T>
434-    {
435-        internal protected List<T> _list=new List<T>();       
436-        public IEnumerator<T> GetEnumerator()
437-        {
438-            return _list.GetEnumerator();
439-        }
440-
441-        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
442-        {
443-            return _list.GetEnumerator();
444-        }
445-        /// <summary>
446-        /// Indexer
447-        /// </summary>
448-        /// <param name="Name">Name</param>
449-        /// <returns></returns>
450-        public T this [string Name]
451-        {
452-            get
453-            {
454-                return _list.Find((f) => f.GetType().GetProperty("Name").GetValue(f, null).ToString().Equals(Name,StringComparison.InvariantCultureIgnoreCase));
455-            }
456-        }
457-        /// <summary>
458-        /// Indexer
459-        /// </summary>
460-        /// <param name="Index">Position</param>
461-        /// <returns></returns>
462-        public T this[int Index]
463-        {
464-            get
465-            {
466-                return _list[Index];
467-            }
468-        }
469-        /// <summary>
470-        /// Number of items in the collection
471-        /// </summary>
472-        public int Count
473-        {
474-            get { return _list.Count; }
475-        }
476-        /// <summary>
477-        /// If a specific name exists in the collection
478-        /// </summary>
479-        /// <param name="Name">The name</param>
480-        /// <returns>True if the name exists</returns>
481-        public bool Exists(string Name)
482-        {
483-            return _list.Exists((f) => f.GetType().GetProperty("Name").GetValue(f, null).ToString().Equals(Name,StringComparison.InvariantCultureIgnoreCase));
484-        }
485-        /// <summary>
486-        /// Removes the item
487-        /// </summary>
488-        /// <param name="Item"></param>
489-        public void Remove(T Item)
490-        {
491-            _list.Remove(Item);
492-        }
493-        /// <summary>
494-        /// Removes the item at the specified index
495-        /// </summary>
496-        /// <param name="index">THe index</param>
497-        public void RemoveAt(int index)
498-        {
499-            _list.RemoveAt(index);
500-        }
501-       
502-        internal void Clear()
503-        {
504-            _list.Clear();
505-        }
506-    }
507-    /// <summary>
508-    /// Collection class for VBA modules
509-    /// </summary>
510-    public class ExcelVbaModuleCollection : ExcelVBACollectionBase<ExcelVBAModule>
511-    {
512-        ExcelVbaProject _project;
513-        internal ExcelVbaModuleCollection (ExcelVbaProject project)
514-     {
515-            _project=project;
516-     }
517-        internal void Add(ExcelVBAModule Item)
518-        {
519-            _list.Add(Item);
520-        }
521-        /// <summary>
522-        /// Adds a new VBA Module
523-        /// </summary>
524-        /// <param name="Name">The name of the module</param>
525-        /// <returns>The module object</returns>
526-        public ExcelVBAModule AddModule(string Name)
527-        {
528-            if (this[Name] != null)
529-            {
530-                throw(new ArgumentException("Vba modulename already exist."));
531-            }
532-            var m = new ExcelVBAModule();
533-            m.Name = Name;
534-            m.Type = eModuleType.Module;
535-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = Name, DataType = eAttributeDataType.String });
536-            m.Type = eModuleType.Module;
537-            _list.Add(m);
538-            return m;
539-        }
540-        /// <summary>
541-        /// Adds a new VBA class
542-        /// </summary>
543-        /// <param name="Name">The name of the class</param>
544-        /// <param name="Exposed">Private or Public not createble</param>
545-        /// <returns>The class object</returns>
546-        public ExcelVBAModule AddClass(string Name, bool Exposed)
547-        {
548-            var m = new ExcelVBAModule();
549-            m.Name = Name;           
550-            m.Type = eModuleType.Class;
551-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = Name, DataType = eAttributeDataType.String });
552-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}", DataType = eAttributeDataType.String });
553-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString });
554-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString });
555-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "False", DataType = eAttributeDataType.NonString });
556-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = Exposed ? "True" : "False", DataType = eAttributeDataType.NonString });
557-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString });
558-            m.Attributes._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "False", DataType = eAttributeDataType.NonString });
559-
560-            //m.Code = _project.GetBlankClassModule(Name, Exposed);
561-            m.Private = !Exposed;
562-            //m.ClassID=
563-            _list.Add(m);
564-            return m;
565-        }
566-    }
567-    /// <summary>
568-    /// A collection of the vba projects references
569-    /// </summary>
570-    public class ExcelVbaReferenceCollection : ExcelVBACollectionBase<ExcelVbaReference>
571-    {       
572-        internal ExcelVbaReferenceCollection()
573-        {
574-
575-        }
576-        /// <summary>
577-        /// Adds a new reference
578-        /// </summary>
579-        /// <param name="Item">The reference object</param>
580-        public void Add(ExcelVbaReference Item)
581-        {
582-            _list.Add(Item);
583-        }
584-    }
585-    /// <summary>
586-    /// A collection of the module level attributes
587-    /// </summary>
588-    public class ExcelVbaModuleAttributesCollection : ExcelVBACollectionBase<ExcelVbaModuleAttribute>
589-    {
590-        internal string GetAttributeText()
591-        {
592-            StringBuilder sb=new StringBuilder();
593-
594-            foreach (var attr in this)
595-            {
596-                sb.AppendFormat("Attribute {0} = {1}\r\n", attr.Name, attr.DataType==eAttributeDataType.String ? "\"" + attr.Value + "\"" : attr.Value);
597-            }
598-            return sb.ToString();
599-        }
600-    }
601-}
602Index: VBA/ExcelVBAProject.cs
603===================================================================
604--- VBA/ExcelVBAProject.cs  (Revision 12462)
605+++ VBA/ExcelVBAProject.cs  (Arbeitskopie)
606@@ -1,1144 +0,0 @@
607-/*******************************************************************************
608- * You may amend and distribute as you like, but don't remove this header!
609- *
610- * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
611- * See http://www.codeplex.com/EPPlus for details.
612- *
613- * Copyright (C) 2011  Jan KÀllman
614- *
615- * All code and executables are provided "as is" with no warranty either express or implied.
616- * The author accepts no liability for any damage or loss of business that this product may cause.
617- *
618- * If you want to understand this code have a look at the Office VBA File Format Structure Specification (MS-OVBA.PDF) or
619- * http://msdn.microsoft.com/en-us/library/cc313094(v=office.12).aspx
620- *
621- * * Code change notes:
622- *
623- * Author              Change            Date
624- *******************************************************************************
625- * Jan KÀllman    Added   26-MAR-2012
626- *******************************************************************************/
627-using System;
628-using System.Collections.Generic;
629-using System.Globalization;
630-using System.Linq;
631-using System.Text;
632-using System.IO;
633-using OfficeOpenXml.Utils;
634-using System.Security.Cryptography.Pkcs;
635-using System.Security.Cryptography.X509Certificates;
636-using System.Security.Cryptography;
637-using System.Text.RegularExpressions;
638-
639-namespace OfficeOpenXml.VBA
640-{
641-    /// <summary>
642-    /// Represents the VBA project part of the package
643-    /// </summary>
644-    public class ExcelVbaProject
645-    {
646-        const string schemaRelVba = "http://schemas.microsoft.com/office/2006/relationships/vbaProject";
647-        internal const string PartUri = @"/xl/vbaProject.bin";
648-        #region Classes & Enums
649-        /// <summary>
650-        /// Type of system where the VBA project was created.
651-        /// </summary>
652-        public enum eSyskind
653-        {
654-            Win16 = 0,
655-            Win32 = 1,
656-            Macintosh = 2,
657-            Win64 = 3
658-        }
659-
660-        #endregion
661-        internal ExcelVbaProject(ExcelWorkbook wb)
662-        {
663-            _wb = wb;
664-            _pck = _wb._package.Package;
665-            References = new ExcelVbaReferenceCollection();
666-            Modules = new ExcelVbaModuleCollection(this);
667-            var rel = _wb.Part.GetRelationshipsByType(schemaRelVba).FirstOrDefault();
668-            if (rel != null)
669-            {
670-                Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
671-                Part = _pck.GetPart(Uri);
672-#if !MONO
673-                GetProject();               
674-#endif
675-            }
676-            else
677-            {
678-                Lcid = 0;
679-                Part = null;
680-            }
681-        }
682-        internal ExcelWorkbook _wb;
683-        internal Packaging.ZipPackage _pck;
684-        #region Dir Stream Properties
685-        /// <summary>
686-        /// System kind. Default Win32.
687-        /// </summary>
688-        public eSyskind SystemKind { get; set; }
689-        /// <summary>
690-        /// Name of the project
691-        /// </summary>
692-        public string Name { get; set; }
693-        /// <summary>
694-        /// A description of the project
695-        /// </summary>
696-        public string Description { get; set; }
697-        /// <summary>
698-        /// A helpfile
699-        /// </summary>
700-        public string HelpFile1 { get; set; }
701-        /// <summary>
702-        /// Secondary helpfile
703-        /// </summary>
704-        public string HelpFile2 { get; set; }
705-        /// <summary>
706-        /// Context if refering the helpfile
707-        /// </summary>
708-        public int HelpContextID { get; set; }
709-        /// <summary>
710-        /// Conditional compilation constants
711-        /// </summary>
712-        public string Constants { get; set; }
713-        /// <summary>
714-        /// Codepage for encoding. Default is current regional setting.
715-        /// </summary>
716-        public int CodePage { get; internal set; }
717-        internal int LibFlags { get; set; }
718-        internal int MajorVersion { get; set; }
719-        internal int MinorVersion { get; set; }
720-        internal int Lcid { get; set; }
721-        internal int LcidInvoke { get; set; }
722-        internal string ProjectID { get; set; }
723-        internal string ProjectStreamText { get; set; }
724-        /// <summary>
725-        /// Project references
726-        /// </summary>       
727-        public ExcelVbaReferenceCollection References { get; set; }
728-        /// <summary>
729-        /// Code Modules (Modules, classes, designer code)
730-        /// </summary>
731-        public ExcelVbaModuleCollection Modules { get; set; }
732-        ExcelVbaSignature _signature = null;
733-        /// <summary>
734-        /// The digital signature
735-        /// </summary>
736-        public ExcelVbaSignature Signature
737-        {
738-            get
739-            {
740-                if (_signature == null)
741-                {
742-                    _signature=new ExcelVbaSignature(Part);
743-                }
744-                return _signature;
745-            }
746-        }
747-        ExcelVbaProtection _protection=null;
748-        /// <summary>
749-        /// VBA protection
750-        /// </summary>
751-        public ExcelVbaProtection Protection
752-        {
753-            get
754-            {
755-                if (_protection == null)
756-                {
757-                    _protection = new ExcelVbaProtection(this);
758-                }
759-                return _protection;
760-            }
761-        }
762-        #endregion
763-#if !MONO
764-        #region Read Project
765-        private void GetProject()
766-        {
767-
768-            var stream = Part.GetStream();
769-            byte[] vba;
770-            vba = new byte[stream.Length];
771-            stream.Read(vba, 0, (int)stream.Length);
772-            Document = new CompoundDocument(vba);
773-
774-            ReadDirStream();
775-            ProjectStreamText = Encoding.GetEncoding(CodePage).GetString(Document.Storage.DataStreams["PROJECT"]);
776-            ReadModules();
777-            ReadProjectProperties();
778-        }
779-        private void ReadModules()
780-        {
781-            foreach (var modul in Modules)
782-            {
783-                var stream = Document.Storage.SubStorage["VBA"].DataStreams[modul.streamName];
784-                var byCode = CompoundDocument.DecompressPart(stream, (int)modul.ModuleOffset);
785-                string code = Encoding.GetEncoding(CodePage).GetString(byCode);
786-                int pos=0;
787-                while(pos+9<code.Length && code.Substring(pos,9)=="Attribute")
788-                {
789-                    int linePos=code.IndexOf("\r\n",pos);
790-                    string[] lineSplit;
791-                    if(linePos>0)
792-                    {
793-                        lineSplit = code.Substring(pos + 9, linePos - pos - 9).Split('=');
794-                    }
795-                    else
796-                    {
797-                        lineSplit=code.Substring(pos+9).Split(new char[]{'='},1);
798-                    }
799-                    if (lineSplit.Length > 1)
800-                    {
801-                        lineSplit[1] = lineSplit[1].Trim();
802-                        var attr =
803-                            new ExcelVbaModuleAttribute()
804-                        {
805-                            Name = lineSplit[0].Trim(),
806-                            DataType = lineSplit[1].StartsWith("\"") ? eAttributeDataType.String : eAttributeDataType.NonString,
807-                            Value = lineSplit[1].StartsWith("\"") ? lineSplit[1].Substring(1, lineSplit[1].Length - 2) : lineSplit[1]
808-                        };
809-                        modul.Attributes._list.Add(attr);
810-                    }
811-                    pos = linePos + 2;
812-                }
813-                modul.Code=code.Substring(pos);
814-            }
815-        }
816-
817-        private void ReadProjectProperties()
818-        {
819-            _protection = new ExcelVbaProtection(this);
820-            string prevPackage = "";
821-            var lines = Regex.Split(ProjectStreamText, "\r\n");
822-            foreach (string line in lines)
823-            {
824-                if (line.StartsWith("["))
825-                {
826-
827-                }
828-                else
829-                {
830-                    var split = line.Split('=');
831-                    if (split.Length > 1 && split[1].Length > 1 && split[1].StartsWith("\"")) //Remove any double qouates
832-                    {
833-                        split[1] = split[1].Substring(1, split[1].Length - 2);
834-                    }
835-                    switch (split[0])
836-                    {
837-                        case "ID":
838-                            ProjectID = split[1];
839-                            break;
840-                        case "Document":
841-                            string mn = split[1].Substring(0, split[1].IndexOf("/&H"));
842-                            Modules[mn].Type = eModuleType.Document;
843-                            break;
844-                        case "Package":
845-                            prevPackage = split[1];
846-                            break;
847-                        case "BaseClass":
848-                            Modules[split[1]].Type = eModuleType.Designer;
849-                            Modules[split[1]].ClassID = prevPackage;
850-                            break;
851-                        case "Module":
852-                            Modules[split[1]].Type = eModuleType.Module;
853-                            break;
854-                        case "Class":
855-                            Modules[split[1]].Type = eModuleType.Class;
856-                            break;
857-                        case "HelpFile":
858-                        case "Name":
859-                        case "HelpContextID":
860-                        case "Description":
861-                        case "VersionCompatible32":
862-                            break;
863-                        //393222000"
864-                        case "CMG":
865-                            byte[] cmg = Decrypt(split[1]);
866-                            _protection.UserProtected = (cmg[0] & 1) != 0;
867-                            _protection.HostProtected = (cmg[0] & 2) != 0;
868-                            _protection.VbeProtected = (cmg[0] & 4) != 0;
869-                            break;
870-                        case "DPB":
871-                            byte[] dpb = Decrypt(split[1]);
872-                            if (dpb.Length >= 28)
873-                            {
874-                                byte reserved = dpb[0];
875-                                var flags = new byte[3];
876-                                Array.Copy(dpb, 1, flags, 0, 3);
877-                                var keyNoNulls = new byte[4];
878-                                _protection.PasswordKey = new byte[4];
879-                                Array.Copy(dpb, 4, keyNoNulls, 0, 4);
880-                                var hashNoNulls = new byte[20];
881-                                _protection.PasswordHash = new byte[20];
882-                                Array.Copy(dpb, 8, hashNoNulls, 0, 20);
883-                                //Handle 0x00 bitwise 2.4.4.3
884-                                for (int i = 0; i < 24; i++)
885-                                {
886-                                    int bit = 128 >> (int)((i % 8));
887-                                    if (i < 4)
888-                                    {
889-                                        if ((int)(flags[0] & bit) == 0)
890-                                        {
891-                                            _protection.PasswordKey[i] = 0;
892-                                        }
893-                                        else
894-                                        {
895-                                            _protection.PasswordKey[i] = keyNoNulls[i];
896-                                        }
897-                                    }
898-                                    else
899-                                    {
900-                                        int flagIndex = (i - i % 8) / 8;
901-                                        if ((int)(flags[flagIndex] & bit) == 0)
902-                                        {
903-                                            _protection.PasswordHash[i - 4] = 0;
904-                                        }
905-                                        else
906-                                        {
907-                                            _protection.PasswordHash[i - 4] = hashNoNulls[i - 4];
908-                                        }
909-                                    }
910-                                }
911-                            }
912-                            break;
913-                        case "GC":
914-                            _protection.VisibilityState = Decrypt(split[1])[0] == 0xFF;
915-
916-                            break;
917-                    }
918-                }
919-            }
920-        }
921-
922-        /// <summary>
923-        /// 2.4.3.3 Decryption
924-        /// </summary>
925-        /// <param name="value">Byte hex string</param>
926-        /// <returns>The decrypted value</returns>
927-        private byte[] Decrypt(string value)
928-        {
929-            byte[] enc = GetByte(value);
930-            byte[] dec = new byte[(value.Length - 1)];
931-            byte seed, version, projKey, ignoredLength;
932-            seed = enc[0];
933-            dec[0] = (byte)(enc[1] ^ seed);
934-            dec[1] = (byte)(enc[2] ^ seed);
935-            for (int i = 2; i < enc.Length - 1; i++)
936-            {
937-                dec[i] = (byte)(enc[i + 1] ^ (enc[i - 1] + dec[i - 1]));
938-            }
939-            version = dec[0];
940-            projKey = dec[1];
941-            ignoredLength = (byte)((seed & 6) / 2);
942-            int datalength = BitConverter.ToInt32(dec, ignoredLength + 2);
943-            var data = new byte[datalength];
944-            Array.Copy(dec, 6 + ignoredLength, data, 0, datalength);
945-            return data;
946-        }
947-        /// <summary>
948-        /// 2.4.3.2 Encryption
949-        /// </summary>
950-        /// <param name="value"></param>
951-        /// <returns>Byte hex string</returns>
952-        private string Encrypt(byte[] value)
953-        {
954-            byte[] seed = new byte[1];
955-            var rn = RandomNumberGenerator.Create();
956-            rn.GetBytes(seed);
957-            BinaryWriter br = new BinaryWriter(new MemoryStream());
958-            byte[] enc = new byte[value.Length + 10];
959-            enc[0] = seed[0];
960-            enc[1] = (byte)(2 ^ seed[0]);
961-
962-            byte projKey = 0;
963-
964-            foreach (var c in ProjectID)
965-            {
966-                projKey += (byte)c;
967-            }
968-            enc[2] = (byte)(projKey ^ seed[0]);
969-            var ignoredLength = (seed[0] & 6) / 2;
970-            for (int i = 0; i < ignoredLength; i++)
971-            {
972-                br.Write(seed[0]);
973-            }
974-            br.Write(value.Length);
975-            br.Write(value);
976-
977-            int pos = 3;
978-            byte pb = projKey;
979-            foreach (var b in ((MemoryStream)br.BaseStream).ToArray())
980-            {
981-                enc[pos] = (byte)(b ^ (enc[pos - 2] + pb));
982-                pos++;
983-                pb = b;
984-            }
985-
986-            return GetString(enc, pos - 1);
987-        }
988-        private string GetString(byte[] value, int max)
989-        {
990-            string ret = "";
991-            for (int i = 0; i <= max; i++)
992-            {
993-                if (value[i] < 16)
994-                {
995-                    ret += "0" + value[i].ToString("x");
996-                }
997-                else
998-                {
999-                    ret += value[i].ToString("x");
1000-                }
1001-            }
1002-            return ret.ToUpper(CultureInfo.InvariantCulture);
1003-        }
1004-        private byte[] GetByte(string value)
1005-        {
1006-            byte[] ret = new byte[value.Length / 2];
1007-            for (int i = 0; i < ret.Length; i++)
1008-            {
1009-                ret[i] = byte.Parse(value.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
1010-            }
1011-            return ret;
1012-        }
1013-        private void ReadDirStream()
1014-        {
1015-            byte[] dir = CompoundDocument.DecompressPart(Document.Storage.SubStorage["VBA"].DataStreams["dir"]);
1016-            MemoryStream ms = new MemoryStream(dir);
1017-            BinaryReader br = new BinaryReader(ms);
1018-            ExcelVbaReference currentRef = null;
1019-            string referenceName = "";
1020-            ExcelVBAModule currentModule = null;
1021-            bool terminate = false;
1022-            while (br.BaseStream.Position < br.BaseStream.Length && terminate == false)
1023-            {
1024-                ushort id = br.ReadUInt16();
1025-                uint size = br.ReadUInt32();
1026-                switch (id)
1027-                {
1028-                    case 0x01:
1029-                        SystemKind = (eSyskind)br.ReadUInt32();
1030-                        break;
1031-                    case 0x02:
1032-                        Lcid = (int)br.ReadUInt32();
1033-                        break;
1034-                    case 0x03:
1035-                        CodePage = (int)br.ReadUInt16();
1036-                        break;
1037-                    case 0x04:
1038-                        Name = GetString(br, size);
1039-                        break;
1040-                    case 0x05:
1041-                        Description = GetUnicodeString(br, size);
1042-                        break;
1043-                    case 0x06:
1044-                        HelpFile1 = GetString(br, size);
1045-                        break;
1046-                    case 0x3D:
1047-                        HelpFile2 = GetString(br, size);
1048-                        break;
1049-                    case 0x07:
1050-                        HelpContextID = (int)br.ReadUInt32();
1051-                        break;
1052-                    case 0x08:
1053-                        LibFlags = (int)br.ReadUInt32();
1054-                        break;
1055-                    case 0x09:
1056-                        MajorVersion = (int)br.ReadUInt32();
1057-                        MinorVersion = (int)br.ReadUInt16();
1058-                        break;
1059-                    case 0x0C:
1060-                        Constants = GetUnicodeString(br, size);
1061-                        break;
1062-                    case 0x0D:
1063-                        uint sizeLibID = br.ReadUInt32();
1064-                        var regRef = new ExcelVbaReference();
1065-                        regRef.Name = referenceName;
1066-                        regRef.ReferenceRecordID = id;
1067-                        regRef.Libid = GetString(br, sizeLibID);
1068-                        uint reserved1 = br.ReadUInt32();
1069-                        ushort reserved2 = br.ReadUInt16();
1070-                        References.Add(regRef);
1071-                        break;
1072-                    case 0x0E:
1073-                        var projRef = new ExcelVbaReferenceProject();
1074-                        projRef.ReferenceRecordID = id;
1075-                        projRef.Name = referenceName;
1076-                        sizeLibID = br.ReadUInt32();
1077-                        projRef.Libid = GetString(br, sizeLibID);
1078-                        sizeLibID = br.ReadUInt32();
1079-                        projRef.LibIdRelative = GetString(br, sizeLibID);
1080-                        projRef.MajorVersion = br.ReadUInt32();
1081-                        projRef.MinorVersion = br.ReadUInt16();
1082-                        References.Add(projRef);
1083-                        break;
1084-                    case 0x0F:
1085-                        ushort modualCount = br.ReadUInt16();
1086-                        break;
1087-                    case 0x13:
1088-                        ushort cookie = br.ReadUInt16();
1089-                        break;
1090-                    case 0x14:
1091-                        LcidInvoke = (int)br.ReadUInt32();
1092-                        break;
1093-                    case 0x16:
1094-                        referenceName = GetUnicodeString(br, size);
1095-                        break;
1096-                    case 0x19:
1097-                        currentModule = new ExcelVBAModule();
1098-                        currentModule.Name = GetUnicodeString(br, size);
1099-                        Modules.Add(currentModule);
1100-                        break;
1101-                    case 0x1A:
1102-                        currentModule.streamName = GetUnicodeString(br, size);
1103-                        break;
1104-                    case 0x1C:
1105-                        currentModule.Description = GetUnicodeString(br, size);
1106-                        break;
1107-                    case 0x1E:
1108-                        currentModule.HelpContext = (int)br.ReadUInt32();
1109-                        break;
1110-                    case 0x21:
1111-                    case 0x22:
1112-                        break;
1113-                    case 0x2B:      //Modul Terminator
1114-                        break;
1115-                    case 0x2C:
1116-                        currentModule.Cookie = br.ReadUInt16();
1117-                        break;
1118-                    case 0x31:
1119-                        currentModule.ModuleOffset = br.ReadUInt32();
1120-                        break;
1121-                    case 0x10:
1122-                        terminate = true;
1123-                        break;
1124-                    case 0x30:
1125-                        var extRef = (ExcelVbaReferenceControl)currentRef;
1126-                        var sizeExt = br.ReadUInt32();
1127-                        extRef.LibIdExternal = GetString(br, sizeExt);
1128-
1129-                        uint reserved4 = br.ReadUInt32();
1130-                        ushort reserved5 = br.ReadUInt16();
1131-                        extRef.OriginalTypeLib = new Guid(br.ReadBytes(16));
1132-                        extRef.Cookie = br.ReadUInt32();
1133-                        break;
1134-                    case 0x33:
1135-                        currentRef = new ExcelVbaReferenceControl();
1136-                        currentRef.ReferenceRecordID = id;
1137-                        currentRef.Name = referenceName;
1138-                        currentRef.Libid = GetString(br, size);
1139-                        References.Add(currentRef);
1140-                        break;
1141-                    case 0x2F:
1142-                        var contrRef = (ExcelVbaReferenceControl)currentRef;
1143-                        contrRef.ReferenceRecordID = id;
1144-
1145-                        var sizeTwiddled = br.ReadUInt32();
1146-                        contrRef.LibIdTwiddled = GetString(br, sizeTwiddled);
1147-                        var r1 = br.ReadUInt32();
1148-                        var r2 = br.ReadUInt16();
1149-
1150-                        break;
1151-                    case 0x25:
1152-                        currentModule.ReadOnly = true;
1153-                        break;
1154-                    case 0x28:
1155-                        currentModule.Private = true;
1156-                        break;
1157-                    default:
1158-                        break;
1159-                }
1160-            }
1161-        }
1162-        #endregion
1163-
1164-        #region Save Project
1165-        internal void Save()
1166-        {
1167-            if (Validate())
1168-            {
1169-                CompoundDocument doc = new CompoundDocument();
1170-                doc.Storage = new CompoundDocument.StoragePart();
1171-                var store = new CompoundDocument.StoragePart();
1172-                doc.Storage.SubStorage.Add("VBA", store);
1173-
1174-                store.DataStreams.Add("_VBA_PROJECT", CreateVBAProjectStream());
1175-                store.DataStreams.Add("dir", CreateDirStream());
1176-                foreach (var module in Modules)
1177-                {
1178-                    store.DataStreams.Add(module.Name, CompoundDocument.CompressPart(Encoding.GetEncoding(CodePage).GetBytes(module.Attributes.GetAttributeText() + module.Code)));
1179-                }
1180-
1181-                //Copy streams from the template, if used.
1182-                if (Document != null)
1183-                {
1184-                    foreach (var ss in Document.Storage.SubStorage)
1185-                    {
1186-                        if (ss.Key != "VBA")
1187-                        {
1188-                            doc.Storage.SubStorage.Add(ss.Key, ss.Value);
1189-                        }
1190-                    }
1191-                    foreach (var s in Document.Storage.DataStreams)
1192-                    {
1193-                        if (s.Key != "dir" && s.Key != "PROJECT" && s.Key != "PROJECTwm")
1194-                        {
1195-                            doc.Storage.DataStreams.Add(s.Key, s.Value);
1196-                        }
1197-                    }
1198-                }
1199-
1200-                doc.Storage.DataStreams.Add("PROJECT", CreateProjectStream());
1201-                doc.Storage.DataStreams.Add("PROJECTwm", CreateProjectwmStream());
1202-
1203-                if (Part == null)
1204-                {
1205-                    Uri = new Uri(PartUri, UriKind.Relative);
1206-                    Part = _pck.CreatePart(Uri, ExcelPackage.schemaVBA);
1207-                    var rel = _wb.Part.CreateRelationship(Uri, Packaging.TargetMode.Internal, schemaRelVba);
1208-                }
1209-                var vbaBuffer=doc.Save();
1210-                var st = Part.GetStream(FileMode.Create);
1211-                st.Write(vbaBuffer, 0, vbaBuffer.Length);
1212-                st.Flush();
1213-                //Save the digital signture
1214-                Signature.Save(this);
1215-            }
1216-        }
1217-
1218-        private bool Validate()
1219-        {
1220-            Description = Description ?? "";
1221-            HelpFile1 = HelpFile1 ?? "";
1222-            HelpFile2 = HelpFile2 ?? "";
1223-            Constants = Constants ?? "";
1224-            return true;
1225-        }
1226-
1227-        /// <summary>
1228-        /// MS-OVBA 2.3.4.1
1229-        /// </summary>
1230-        /// <returns></returns>
1231-        private byte[] CreateVBAProjectStream()
1232-        {
1233-            BinaryWriter bw = new BinaryWriter(new MemoryStream());
1234-            bw.Write((ushort)0x61CC); //Reserved1
1235-            bw.Write((ushort)0xFFFF); //Version
1236-            bw.Write((byte)0x0); //Reserved3
1237-            bw.Write((ushort)0x0); //Reserved4
1238-            return ((MemoryStream)bw.BaseStream).ToArray();
1239-        }
1240-        /// <summary>
1241-        /// MS-OVBA 2.3.4.1
1242-        /// </summary>
1243-        /// <returns></returns>
1244-        private byte[] CreateDirStream()
1245-        {
1246-            BinaryWriter bw = new BinaryWriter(new MemoryStream());
1247-
1248-            /****** PROJECTINFORMATION Record ******/
1249-            bw.Write((ushort)1);        //ID
1250-            bw.Write((uint)4);          //Size
1251-            bw.Write((uint)SystemKind); //SysKind
1252-
1253-            bw.Write((ushort)2);        //ID
1254-            bw.Write((uint)4);          //Size
1255-            bw.Write((uint)Lcid);       //Lcid
1256-
1257-            bw.Write((ushort)0x14);     //ID
1258-            bw.Write((uint)4);          //Size
1259-            bw.Write((uint)LcidInvoke); //Lcid Invoke
1260-
1261-            bw.Write((ushort)3);        //ID
1262-            bw.Write((uint)2);          //Size
1263-            bw.Write((ushort)CodePage);   //Codepage
1264-
1265-            //ProjectName
1266-            bw.Write((ushort)4);                                            //ID
1267-            bw.Write((uint)Name.Length);                             //Size
1268-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Name)); //Project Name
1269-
1270-            //Description
1271-            bw.Write((ushort)5);                                            //ID
1272-            bw.Write((uint)Description.Length);                             //Size
1273-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Description)); //Project Name
1274-            bw.Write((ushort)0x40);                                           //ID
1275-            bw.Write((uint)Description.Length*2);                           //Size
1276-            bw.Write(Encoding.Unicode.GetBytes(Description));               //Project Description
1277-
1278-            //Helpfiles
1279-            bw.Write((ushort)6);                                           //ID
1280-            bw.Write((uint)HelpFile1.Length);                              //Size
1281-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile1));  //HelpFile1           
1282-            bw.Write((ushort)0x3D);                                           //ID
1283-            bw.Write((uint)HelpFile2.Length);                              //Size
1284-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile2));  //HelpFile2
1285-
1286-            //Help context id
1287-            bw.Write((ushort)7);            //ID
1288-            bw.Write((uint)4);              //Size
1289-            bw.Write((uint)HelpContextID);  //Help context id
1290-
1291-            //Libflags
1292-            bw.Write((ushort)8);            //ID
1293-            bw.Write((uint)4);              //Size
1294-            bw.Write((uint)0);  //Help context id
1295-
1296-            //Vba Version
1297-            bw.Write((ushort)9);            //ID
1298-            bw.Write((uint)4);              //Reserved
1299-            bw.Write((uint)MajorVersion);   //Reserved
1300-            bw.Write((ushort)MinorVersion); //Help context id
1301-
1302-            //Constants
1303-            bw.Write((ushort)0x0C);           //ID
1304-            bw.Write((uint)Constants.Length);              //Size
1305-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Constants));              //Help context id
1306-            bw.Write((ushort)0x3C);                                           //ID
1307-            bw.Write((uint)Constants.Length/2);                              //Size
1308-            bw.Write(Encoding.Unicode.GetBytes(Constants));  //HelpFile2
1309-
1310-            /****** PROJECTREFERENCES Record ******/
1311-            foreach (var reference in References)
1312-            {
1313-                WriteNameReference(bw, reference);
1314-
1315-                if (reference.ReferenceRecordID == 0x2F)
1316-                {
1317-                    WriteControlReference(bw, reference);
1318-                }
1319-                else if (reference.ReferenceRecordID == 0x33)
1320-                {
1321-                    WriteOrginalReference(bw, reference);
1322-                }
1323-                else if (reference.ReferenceRecordID == 0x0D)
1324-                {
1325-                    WriteRegisteredReference(bw, reference);
1326-                }
1327-                else if (reference.ReferenceRecordID == 0x0E)
1328-                {
1329-                    WriteProjectReference(bw, reference);
1330-                }
1331-            }
1332-
1333-            bw.Write((ushort)0x0F);
1334-            bw.Write((uint)0x02);
1335-            bw.Write((ushort)Modules.Count);
1336-            bw.Write((ushort)0x13);
1337-            bw.Write((uint)0x02);
1338-            bw.Write((ushort)0xFFFF);
1339-
1340-            foreach (var module in Modules)
1341-            {
1342-                WriteModuleRecord(bw, module);
1343-            }
1344-            bw.Write((ushort)0x10);             //Terminator
1345-            bw.Write((uint)0);             
1346-
1347-            return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray());
1348-        }
1349-
1350-        private void WriteModuleRecord(BinaryWriter bw, ExcelVBAModule module)
1351-        {
1352-            bw.Write((ushort)0x19);
1353-            bw.Write((uint)module.Name.Length);
1354-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name));     //Name
1355-
1356-            bw.Write((ushort)0x47);
1357-            bw.Write((uint)module.Name.Length*2);
1358-            bw.Write(Encoding.Unicode.GetBytes(module.Name));                   //Name
1359-
1360-            bw.Write((ushort)0x1A);
1361-            bw.Write((uint)module.Name.Length);
1362-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name));     //Stream Name 
1363-
1364-            bw.Write((ushort)0x32);
1365-            bw.Write((uint)module.Name.Length*2);
1366-            bw.Write(Encoding.Unicode.GetBytes(module.Name));                   //Stream Name
1367-
1368-            module.Description = module.Description ?? "";
1369-            bw.Write((ushort)0x1C);
1370-            bw.Write((uint)module.Description.Length);
1371-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Description));     //Description
1372-
1373-            bw.Write((ushort)0x48);
1374-            bw.Write((uint)module.Description.Length*2);
1375-            bw.Write(Encoding.Unicode.GetBytes(module.Description));                   //Description
1376-
1377-            bw.Write((ushort)0x31);
1378-            bw.Write((uint)4);
1379-            bw.Write((uint)0);                              //Module Stream Offset (No PerformanceCache)
1380-
1381-            bw.Write((ushort)0x1E);
1382-            bw.Write((uint)4);
1383-            bw.Write((uint)module.HelpContext);            //Help context ID
1384-
1385-            bw.Write((ushort)0x2C);
1386-            bw.Write((uint)2);
1387-            bw.Write((ushort)0xFFFF);            //Help context ID
1388-
1389-            bw.Write((ushort)(module.Type == eModuleType.Module ? 0x21 : 0x22));
1390-            bw.Write((uint)0);
1391-
1392-            if (module.ReadOnly)
1393-            {
1394-                bw.Write((ushort)0x25);
1395-                bw.Write((uint)0);              //Readonly
1396-            }
1397-
1398-            if (module.Private)
1399-            {
1400-                bw.Write((ushort)0x28);
1401-                bw.Write((uint)0);              //Private
1402-            }
1403-
1404-            bw.Write((ushort)0x2B);             //Terminator
1405-            bw.Write((uint)0);             
1406-        }
1407-
1408-        private void WriteNameReference(BinaryWriter bw, ExcelVbaReference reference)
1409-        {
1410-            //Name record
1411-            bw.Write((ushort)0x16);                                             //ID
1412-            bw.Write((uint)reference.Name.Length);                              //Size
1413-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Name));  //HelpFile1
1414-            bw.Write((ushort)0x3E);                                             //ID
1415-            bw.Write((uint)reference.Name.Length * 2);                            //Size
1416-            bw.Write(Encoding.Unicode.GetBytes(reference.Name));                //HelpFile2
1417-        }
1418-        private void WriteControlReference(BinaryWriter bw, ExcelVbaReference reference)
1419-        {
1420-            WriteOrginalReference(bw, reference);
1421-
1422-            bw.Write((ushort)0x2F);
1423-            var controlRef=(ExcelVbaReferenceControl)reference;
1424-            bw.Write((uint)(4 + controlRef.LibIdTwiddled.Length + 4 + 2));    // Size of SizeOfLibidTwiddled, LibidTwiddled, Reserved1, and Reserved2.
1425-            bw.Write((uint)controlRef.LibIdTwiddled.Length);                              //Size           
1426-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdTwiddled));  //LibID
1427-            bw.Write((uint)0);      //Reserved1
1428-            bw.Write((ushort)0);    //Reserved2
1429-            WriteNameReference(bw, reference);  //Name record again
1430-            bw.Write((ushort)0x30); //Reserved3
1431-            bw.Write((uint)(4 + controlRef.LibIdExternal.Length + 4 + 2 + 16 + 4));    //Size of SizeOfLibidExtended, LibidExtended, Reserved4, Reserved5, OriginalTypeLib, and Cookie
1432-            bw.Write((uint)controlRef.LibIdExternal.Length);                              //Size           
1433-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdExternal));  //LibID
1434-            bw.Write((uint)0);      //Reserved4
1435-            bw.Write((ushort)0);    //Reserved5
1436-            bw.Write(controlRef.OriginalTypeLib.ToByteArray());
1437-            bw.Write((uint)controlRef.Cookie);      //Cookie
1438-        }
1439-
1440-        private void WriteOrginalReference(BinaryWriter bw, ExcelVbaReference reference)
1441-        {
1442-            bw.Write((ushort)0x33);
1443-            bw.Write((uint)reference.Libid.Length);
1444-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid));  //LibID
1445-        }
1446-        private void WriteProjectReference(BinaryWriter bw, ExcelVbaReference reference)
1447-        {
1448-            bw.Write((ushort)0x0E);
1449-            var projRef = (ExcelVbaReferenceProject)reference;
1450-            bw.Write((uint)(4 + projRef.Libid.Length + 4 + projRef.LibIdRelative.Length+4+2));
1451-            bw.Write((uint)projRef.Libid.Length);
1452-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.Libid));  //LibAbsolute
1453-            bw.Write((uint)projRef.LibIdRelative.Length);
1454-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.LibIdRelative));  //LibIdRelative
1455-            bw.Write(projRef.MajorVersion);
1456-            bw.Write(projRef.MinorVersion);
1457-        }
1458-
1459-        private void WriteRegisteredReference(BinaryWriter bw, ExcelVbaReference reference)
1460-        {
1461-            bw.Write((ushort)0x0D);
1462-            bw.Write((uint)(4+reference.Libid.Length+4+2));
1463-            bw.Write((uint)reference.Libid.Length);
1464-            bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid));  //LibID           
1465-            bw.Write((uint)0);      //Reserved1
1466-            bw.Write((ushort)0);    //Reserved2
1467-        }
1468-
1469-        private byte[] CreateProjectwmStream()
1470-        {
1471-            BinaryWriter bw = new BinaryWriter(new MemoryStream());
1472-
1473-            foreach (var module in Modules)
1474-            {
1475-                bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name));     //Name
1476-                bw.Write((byte)0); //Null
1477-                bw.Write(Encoding.Unicode.GetBytes(module.Name));                   //Name
1478-                bw.Write((ushort)0); //Null
1479-            }
1480-            bw.Write((ushort)0); //Null
1481-            return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray());
1482-        }       
1483-        private byte[] CreateProjectStream()
1484-        {
1485-            StringBuilder sb = new StringBuilder();
1486-            sb.AppendFormat("ID=\"{0}\"\r\n", ProjectID);
1487-            foreach(var module in Modules)
1488-            {
1489-                if (module.Type == eModuleType.Document)
1490-                {
1491-                    sb.AppendFormat("Document={0}/&H00000000\r\n", module.Name);
1492-                }
1493-                else if (module.Type == eModuleType.Module)
1494-                {
1495-                    sb.AppendFormat("Module={0}\r\n", module.Name);
1496-                }
1497-                else if (module.Type == eModuleType.Class)
1498-                {
1499-                    sb.AppendFormat("Class={0}\r\n", module.Name);
1500-                }
1501-                else
1502-                {
1503-                    //Designer
1504-                    sb.AppendFormat("Package={0}\r\n", module.ClassID);
1505-                    sb.AppendFormat("BaseClass={0}\r\n", module.Name);
1506-                }
1507-            }
1508-            if (HelpFile1 != "")
1509-            {
1510-                sb.AppendFormat("HelpFile={0}\r\n", HelpFile1);
1511-            }
1512-            sb.AppendFormat("Name=\"{0}\"\r\n", Name);
1513-            sb.AppendFormat("HelpContextID={0}\r\n", HelpContextID);
1514-
1515-            if (!string.IsNullOrEmpty(Description))
1516-            {
1517-                sb.AppendFormat("Description=\"{0}\"\r\n", Description);
1518-            }
1519-            sb.AppendFormat("VersionCompatible32=\"393222000\"\r\n");
1520-
1521-            sb.AppendFormat("CMG=\"{0}\"\r\n", WriteProtectionStat());
1522-            sb.AppendFormat("DPB=\"{0}\"\r\n", WritePassword());
1523-            sb.AppendFormat("GC=\"{0}\"\r\n\r\n", WriteVisibilityState());
1524-
1525-            sb.Append("[Host Extender Info]\r\n");
1526-            sb.Append("&H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000\r\n");
1527-            sb.Append("\r\n");
1528-            sb.Append("[Workspace]\r\n");
1529-            foreach(var module in Modules)
1530-            {
1531-                sb.AppendFormat("{0}=0, 0, 0, 0, C \r\n",module.Name);             
1532-            }
1533-            string s = sb.ToString();
1534-            return Encoding.GetEncoding(CodePage).GetBytes(s);
1535-        }
1536-        private string WriteProtectionStat()
1537-        {
1538-            int stat=(_protection.UserProtected ? 1:0) | 
1539-                     (_protection.HostProtected ? 2:0) |
1540-                     (_protection.VbeProtected ? 4:0);
1541-
1542-            return Encrypt(BitConverter.GetBytes(stat));   
1543-        }
1544-        private string WritePassword()
1545-        {
1546-            byte[] nullBits=new byte[3];
1547-            byte[] nullKey = new byte[4];
1548-            byte[] nullHash = new byte[20];
1549-            if (Protection.PasswordKey == null)
1550-            {
1551-                return Encrypt(new byte[] { 0 });
1552-            }
1553-            else
1554-            {
1555-                Array.Copy(Protection.PasswordKey, nullKey, 4);
1556-                Array.Copy(Protection.PasswordHash, nullHash, 20);
1557-
1558-                //Set Null bits
1559-                for (int i = 0; i < 24; i++)
1560-                {
1561-                    byte bit = (byte)(128 >> (int)((i % 8)));
1562-                    if (i < 4)
1563-                    {
1564-                        if (nullKey[i] == 0)
1565-                        {
1566-                            nullKey[i] = 1;
1567-                        }
1568-                        else
1569-                        {
1570-                            nullBits[0] |= bit;
1571-                        }
1572-                    }
1573-                    else
1574-                    {
1575-                        if (nullHash[i - 4] == 0)
1576-                        {
1577-                            nullHash[i - 4] = 1;
1578-                        }
1579-                        else
1580-                        {
1581-                            int byteIndex = (i - i % 8) / 8;
1582-                            nullBits[byteIndex] |= bit;
1583-                        }
1584-                    }
1585-                }
1586-                //Write the Password Hash Data Structure (2.4.4.1)
1587-                BinaryWriter bw = new BinaryWriter(new MemoryStream());
1588-                bw.Write((byte)0xFF);
1589-                bw.Write(nullBits);
1590-                bw.Write(nullKey);
1591-                bw.Write(nullHash);
1592-                bw.Write((byte)0);
1593-                return Encrypt(((MemoryStream)bw.BaseStream).ToArray());
1594-            }
1595-        }
1596-        private string WriteVisibilityState()
1597-        {
1598-            return Encrypt(new byte[] { (byte)(Protection.VisibilityState ? 0xFF : 0) });
1599-        }
1600-        #endregion
1601-        private string GetString(BinaryReader br, uint size)
1602-        {
1603-            return GetString(br, size, System.Text.Encoding.GetEncoding(CodePage));
1604-        }
1605-        private string GetString(BinaryReader br, uint size, Encoding enc)
1606-        {
1607-            if (size > 0)
1608-            {
1609-                byte[] byteTemp = new byte[size];
1610-                byteTemp = br.ReadBytes((int)size);
1611-                return enc.GetString(byteTemp);
1612-            }
1613-            else
1614-            {
1615-                return "";
1616-            }
1617-        }
1618-        private string GetUnicodeString(BinaryReader br, uint size)
1619-        {
1620-            string s = GetString(br, size);
1621-            int reserved = br.ReadUInt16();
1622-            uint sizeUC = br.ReadUInt32();
1623-            string sUC = GetString(br, sizeUC, System.Text.Encoding.Unicode);
1624-            return sUC.Length == 0 ? s : sUC;
1625-        }
1626-        internal CompoundDocument Document { get; set; }
1627-#endif
1628-        internal Packaging.ZipPackagePart Part { get; set; }
1629-        internal Uri Uri { get; private set; }
1630-#if !MONO
1631-        /// <summary>
1632-        /// Create a new VBA Project
1633-        /// </summary>
1634-        internal void Create()
1635-        {
1636-            if(Lcid>0)
1637-            {
1638-                throw (new InvalidOperationException("Package already contains a VBAProject"));
1639-            }
1640-            ProjectID = "{5DD90D76-4904-47A2-AF0D-D69B4673604E}";
1641-            Name = "VBAProject";
1642-            SystemKind = eSyskind.Win32;            //Default
1643-            Lcid = 1033;                            //English - United States
1644-            LcidInvoke = 1033;                      //English - United States
1645-            CodePage = Encoding.Default.CodePage;
1646-            MajorVersion = 1361024421;
1647-            MinorVersion = 6;
1648-            HelpContextID = 0;
1649-            Modules.Add(new ExcelVBAModule(_wb.CodeNameChange) { Name = "ThisWorkbook", Code = "", Attributes=GetDocumentAttributes("ThisWorkbook", "0{00020819-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 });
1650-            foreach (var sheet in _wb.Worksheets)
1651-            {
1652-                var name = GetModuleNameFromWorksheet(sheet);
1653-                if (!Modules.Exists(name))
1654-                {
1655-                    Modules.Add(new ExcelVBAModule(sheet.CodeNameChange) { Name = name, Code = "", Attributes = GetDocumentAttributes(sheet.Name, "0{00020820-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 });
1656-                }
1657-            }
1658-            _protection = new ExcelVbaProtection(this) { UserProtected = false, HostProtected = false, VbeProtected = false, VisibilityState = true };
1659-        }
1660-
1661-        internal string GetModuleNameFromWorksheet(ExcelWorksheet sheet)
1662-        {
1663-            var name = sheet.Name;
1664-            if (name.Any(c => c > 255) || this.Modules[name] != null)
1665-            {
1666-                int i = sheet.PositionID;
1667-                name = "Sheet" + i.ToString();
1668-                while (this.Modules[name] != null)
1669-                {
1670-                    name = "Sheet" + (++i).ToString(); ;
1671-                }
1672-            }           
1673-            return name;
1674-        }
1675-        internal ExcelVbaModuleAttributesCollection GetDocumentAttributes(string name, string clsid)
1676-        {
1677-            var attr = new ExcelVbaModuleAttributesCollection();
1678-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = name, DataType = eAttributeDataType.String });
1679-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = clsid, DataType = eAttributeDataType.String });
1680-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString });
1681-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString });
1682-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "True", DataType = eAttributeDataType.NonString });
1683-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = "False", DataType = eAttributeDataType.NonString });
1684-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString });
1685-            attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "True", DataType = eAttributeDataType.NonString });
1686-
1687-            return attr;
1688-        }
1689-
1690-
1691-        //internal string GetBlankDocumentModule(string name, string clsid)
1692-        //{
1693-        //    string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name);
1694-        //    ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", clsid);  //Microsoft.Office.Interop.Excel.WorksheetClass
1695-        //    ret += "Attribute VB_GlobalNameSpace = False\r\n";
1696-        //    ret += "Attribute VB_Creatable = False\r\n";
1697-        //    ret += "Attribute VB_PredeclaredId = True\r\n";
1698-        //    ret += "Attribute VB_Exposed = True\r\n";
1699-        //    ret += "Attribute VB_TemplateDerived = False\r\n";
1700-        //    ret += "Attribute VB_Customizable = True";
1701-        //    return ret;
1702-        //}
1703-        //internal string GetBlankModule(string name)
1704-        //{
1705-        //    return string.Format("Attribute VB_Name = \"{0}\"\r\n", name);
1706-        //}
1707-        //internal string GetBlankClassModule(string name, bool exposed)
1708-        //{
1709-        //    string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name);
1710-        //    ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}"); 
1711-        //    ret += "Attribute VB_GlobalNameSpace = False\r\n";
1712-        //    ret += "Attribute VB_Creatable = False\r\n";
1713-        //    ret += "Attribute VB_PredeclaredId = False\r\n";
1714-        //    ret += string.Format("Attribute VB_Exposed = {0}\r\n", exposed ? "True" : "False");
1715-        //    ret += "Attribute VB_TemplateDerived = False\r\n";
1716-        //    ret += "Attribute VB_Customizable = False\r\n";
1717-        //    return ret;
1718-        //}
1719-#endif
1720-        /// <summary>
1721-        /// Remove the project from the package
1722-        /// </summary>
1723-        public void Remove()
1724-        {
1725-            if (Part == null) return;
1726-
1727-            foreach (var rel in Part.GetRelationships())
1728-            {
1729-                _pck.DeleteRelationship(rel.Id);
1730-            }
1731-            if (_pck.PartExists(Uri))
1732-            {
1733-                _pck.DeletePart(Uri);
1734-            }
1735-            Part = null;
1736-            Modules.Clear();
1737-            References.Clear();
1738-            Lcid = 0;
1739-            LcidInvoke = 0;
1740-            CodePage = 0;
1741-            MajorVersion = 0;
1742-            MinorVersion = 0;
1743-            HelpContextID = 0;
1744-        }
1745-        public override string ToString()
1746-        {
1747-            return Name;
1748-        }
1749-    }
1750-}
1751Index: VBA/ExcelVBAReference.cs
1752===================================================================
1753--- VBA/ExcelVBAReference.cs  (Revision 12462)
1754+++ VBA/ExcelVBAReference.cs  (Arbeitskopie)
1755@@ -1,129 +0,0 @@
1756-/*******************************************************************************
1757- * You may amend and distribute as you like, but don't remove this header!
1758- *
1759- * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
1760- * See http://www.codeplex.com/EPPlus for details.
1761- *
1762- * Copyright (C) 2011  Jan KÀllman
1763- *
1764- * This library is free software; you can redistribute it and/or
1765- * modify it under the terms of the GNU Lesser General Public
1766- * License as published by the Free Software Foundation; either
1767- * version 2.1 of the License, or (at your option) any later version.
1768-
1769- * This library is distributed in the hope that it will be useful,
1770- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1771- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
1772- * See the GNU Lesser General Public License for more details.
1773- *
1774- * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
1775- * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
1776- *
1777- * All code and executables are provided "as is" with no warranty either express or implied.
1778- * The author accepts no liability for any damage or loss of business that this product may cause.
1779- *
1780- * Code change notes:
1781- *
1782- * Author              Change            Date
1783- *******************************************************************************
1784- * Jan KÀllman    Added   26-MAR-2012
1785- *******************************************************************************/
1786-using System;
1787-using System.Collections.Generic;
1788-using System.Linq;
1789-using System.Text;
1790-
1791-namespace OfficeOpenXml.VBA
1792-{
1793-    /// <summary>
1794-    /// A VBA reference
1795-    /// </summary>
1796-    public class ExcelVbaReference
1797-    {
1798-        /// <summary>
1799-        /// Constructor.
1800-        /// Defaults ReferenceRecordID to 0xD
1801-        /// </summary>
1802-        public ExcelVbaReference()
1803-        {
1804-            ReferenceRecordID = 0xD;
1805-        }
1806-        /// <summary>
1807-        /// The reference record ID. See MS-OVBA documentation for more info.
1808-        /// </summary>
1809-        public int ReferenceRecordID { get; internal set; }
1810-        /// <summary>
1811-        /// The name of the reference
1812-        /// </summary>
1813-        public string Name { get; set; }
1814-        /// <summary>
1815-        /// LibID
1816-        /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES
1817-        /// </summary>
1818-        public string Libid { get; set; }
1819-        /// <summary>
1820-        /// A string representation of the object (the Name)
1821-        /// </summary>
1822-        /// <returns></returns>
1823-        public override string ToString()
1824-        {
1825-            return Name;
1826-        }
1827-    }
1828-    /// <summary>
1829-    /// A reference to a twiddled type library
1830-    /// </summary>
1831-    public class ExcelVbaReferenceControl : ExcelVbaReference
1832-    {
1833-        /// <summary>
1834-        /// Constructor.
1835-        /// Sets ReferenceRecordID to 0x2F
1836-        /// </summary>
1837-        public ExcelVbaReferenceControl()
1838-        {
1839-            ReferenceRecordID = 0x2F;
1840-        }
1841-        /// <summary>
1842-        /// LibIdExternal
1843-        /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES
1844-        /// </summary>
1845-        public string LibIdExternal { get; set; }
1846-        /// <summary>
1847-        /// LibIdTwiddled
1848-        /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES
1849-        /// </summary>
1850-        public string LibIdTwiddled { get; set; }
1851-        /// <summary>
1852-        /// A GUID that specifies the Automation type library the extended type library was generated from.
1853-        /// </summary>
1854-        public Guid OriginalTypeLib { get; set; }
1855-        internal uint Cookie { get; set; }
1856-    }
1857-    /// <summary>
1858-    /// A reference to an external VBA project
1859-    /// </summary>
1860-    public class ExcelVbaReferenceProject : ExcelVbaReference
1861-    {
1862-        /// <summary>
1863-        /// Constructor.
1864-        /// Sets ReferenceRecordID to 0x0E
1865-        /// </summary>
1866-        public ExcelVbaReferenceProject()
1867-        {
1868-            ReferenceRecordID = 0x0E;
1869-        }
1870-        /// <summary>
1871-        /// LibIdRelative
1872-        /// For more info check MS-OVBA 2.1.1.8 LibidReference and 2.3.4.2.2 PROJECTREFERENCES
1873-        /// </summary>
1874-        public string LibIdRelative { get; set; }
1875-        /// <summary>
1876-        /// Major version of the referenced VBA project
1877-        /// </summary>
1878-        public uint MajorVersion { get; set; }
1879-        /// <summary>
1880-        /// Minor version of the referenced VBA project
1881-        /// </summary>
1882-        public ushort MinorVersion { get; set; }
1883-    }
1884-}
1885Index: VBA/ExcelVBASignature.cs
1886===================================================================
1887--- VBA/ExcelVBASignature.cs  (Revision 12462)
1888+++ VBA/ExcelVBASignature.cs  (Arbeitskopie)
1889@@ -1,384 +0,0 @@
1890-/*******************************************************************************
1891- * You may amend and distribute as you like, but don't remove this header!
1892- *
1893- * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
1894- * See http://www.codeplex.com/EPPlus for details.
1895- *
1896- * Copyright (C) 2011  Jan KÀllman
1897- *
1898- * This library is free software; you can redistribute it and/or
1899- * modify it under the terms of the GNU Lesser General Public
1900- * License as published by the Free Software Foundation; either
1901- * version 2.1 of the License, or (at your option) any later version.
1902-
1903- * This library is distributed in the hope that it will be useful,
1904- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1905- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
1906- * See the GNU Lesser General Public License for more details.
1907- *
1908- * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
1909- * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
1910- *
1911- * All code and executables are provided "as is" with no warranty either express or implied.
1912- * The author accepts no liability for any damage or loss of business that this product may cause.
1913- *
1914- * Code change notes:
1915- *
1916- * Author              Change            Date
1917- *******************************************************************************
1918- * Jan KÀllman    Added   26-MAR-2012
1919- *******************************************************************************/
1920-using System;
1921-using System.Collections.Generic;
1922-using System.Linq;
1923-using System.Text;
1924-using System.Security.Cryptography.X509Certificates;
1925-using System.Security.Cryptography.Pkcs;
1926-using OfficeOpenXml.Utils;
1927-using System.IO;
1928-
1929-namespace OfficeOpenXml.VBA
1930-{
1931-    /// <summary>
1932-    /// The code signature properties of the project
1933-    /// </summary>
1934-    public class ExcelVbaSignature
1935-    {
1936-        const string schemaRelVbaSignature = "http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature";
1937-        Packaging.ZipPackagePart _vbaPart = null;
1938-        internal ExcelVbaSignature(Packaging.ZipPackagePart vbaPart)
1939-        {
1940-            _vbaPart = vbaPart;
1941-            GetSignature();
1942-        }
1943-        private void GetSignature()
1944-        {
1945-            if (_vbaPart == null) return;
1946-            var rel = _vbaPart.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault();
1947-            if (rel != null)
1948-            {
1949-                Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
1950-                Part = _vbaPart.Package.GetPart(Uri);
1951-
1952-                var stream = Part.GetStream();
1953-                BinaryReader br = new BinaryReader(stream);
1954-                uint cbSignature = br.ReadUInt32();       
1955-                uint signatureOffset = br.ReadUInt32();     //44 ??
1956-                uint cbSigningCertStore = br.ReadUInt32(); 
1957-                uint certStoreOffset = br.ReadUInt32();     
1958-                uint cbProjectName = br.ReadUInt32();       
1959-                uint projectNameOffset = br.ReadUInt32();   
1960-                uint fTimestamp = br.ReadUInt32();
1961-                uint cbTimestampUrl = br.ReadUInt32();
1962-                uint timestampUrlOffset = br.ReadUInt32(); 
1963-                byte[] signature = br.ReadBytes((int)cbSignature);
1964-                uint version = br.ReadUInt32();
1965-                uint fileType = br.ReadUInt32();
1966-
1967-                uint id = br.ReadUInt32();
1968-                while (id != 0)
1969-                {
1970-                    uint encodingType = br.ReadUInt32();
1971-                    uint length = br.ReadUInt32();
1972-                    if (length > 0)
1973-                    {
1974-                        byte[] value = br.ReadBytes((int)length);
1975-                        switch (id)
1976-                        {
1977-                            //Add property values here...
1978-                            case 0x20:
1979-                                Certificate = new X509Certificate2(value);
1980-                                break;
1981-                            default:
1982-                                break;
1983-                        }
1984-                    }
1985-                    id = br.ReadUInt32();
1986-                }
1987-                uint endel1 = br.ReadUInt32();  //0
1988-                uint endel2 = br.ReadUInt32();  //0
1989-                ushort rgchProjectNameBuffer = br.ReadUInt16();
1990-                ushort rgchTimestampBuffer = br.ReadUInt16();
1991-                Verifier = new SignedCms();
1992-                Verifier.Decode(signature);
1993-            }
1994-            else
1995-            {
1996-                Certificate = null;
1997-                Verifier = null;
1998-            }
1999-        }
2000-        //Create Oid from a bytearray
2001-        //private string ReadHash(byte[] content)
2002-        //{
2003-        //    StringBuilder builder = new StringBuilder();
2004-        //    int offset = 0x6;
2005-        //    if (0 < (content.Length))
2006-        //    {
2007-        //        byte num = content[offset];
2008-        //        byte num2 = (byte)(num / 40);
2009-        //        builder.Append(num2.ToString(null, null));
2010-        //        builder.Append(".");
2011-        //        num2 = (byte)(num % 40);
2012-        //        builder.Append(num2.ToString(null, null));
2013-        //        ulong num3 = 0L;
2014-        //        for (int i = offset + 1; i < content.Length; i++)
2015-        //        {
2016-        //            num2 = content[i];
2017-        //            num3 = (ulong)(ulong)(num3 << 7) + ((byte)(num2 & 0x7f));
2018-        //            if ((num2 & 0x80) == 0)
2019-        //            {
2020-        //                builder.Append(".");
2021-        //                builder.Append(num3.ToString(null, null));
2022-        //                num3 = 0L;
2023-        //            }
2024-        //            //1.2.840.113549.2.5
2025-        //        }
2026-        //    }
2027-
2028-
2029-        //    string oId = builder.ToString();
2030-
2031-        //    return oId;
2032-        //}
2033-        internal void Save(ExcelVbaProject proj)
2034-        {
2035-            if (Certificate == null)
2036-            {
2037-                return;
2038-            }
2039-           
2040-            if (Certificate.HasPrivateKey==false)    //No signature. Remove any Signature part
2041-            {
2042-                var storeCert = GetCertFromStore(StoreLocation.CurrentUser);
2043-                if (storeCert == null)
2044-                {
2045-                    storeCert = GetCertFromStore(StoreLocation.LocalMachine);
2046-                }
2047-                if (storeCert != null && storeCert.HasPrivateKey == true)
2048-                {
2049-                    Certificate = storeCert;
2050-                }
2051-                else
2052-                {
2053-                    foreach (var r in Part.GetRelationships())
2054-                    {
2055-                        Part.DeleteRelationship(r.Id);
2056-                    }
2057-                    Part.Package.DeletePart(Part.Uri);
2058-                    return;
2059-                }
2060-            }
2061-            var ms = new MemoryStream();
2062-            var bw = new BinaryWriter(ms);
2063-
2064-            byte[] certStore = GetCertStore();
2065-
2066-            byte[] cert = SignProject(proj);
2067-            bw.Write((uint)cert.Length);
2068-            bw.Write((uint)44);                  //?? 36 ref inside cert ??
2069-            bw.Write((uint)certStore.Length);    //cbSigningCertStore
2070-            bw.Write((uint)(cert.Length + 44));  //certStoreOffset
2071-            bw.Write((uint)0);                   //cbProjectName
2072-            bw.Write((uint)(cert.Length + certStore.Length + 44));    //projectNameOffset
2073-            bw.Write((uint)0);    //fTimestamp
2074-            bw.Write((uint)0);    //cbTimestampUrl
2075-            bw.Write((uint)(cert.Length + certStore.Length + 44 + 2));    //timestampUrlOffset
2076-            bw.Write(cert);
2077-            bw.Write(certStore);
2078-            bw.Write((ushort)0);//rgchProjectNameBuffer
2079-            bw.Write((ushort)0);//rgchTimestampBuffer
2080-            bw.Write((ushort)0);
2081-            bw.Flush();
2082-
2083-            var rel = proj.Part.GetRelationshipsByType(schemaRelVbaSignature).FirstOrDefault();
2084-            if (Part == null)
2085-            {
2086-
2087-                if (rel != null)
2088-                {
2089-                    Uri = rel.TargetUri;
2090-                    Part = proj._pck.GetPart(rel.TargetUri);
2091-                }
2092-                else
2093-                {
2094-                    Uri = new Uri("/xl/vbaProjectSignature.bin", UriKind.Relative);
2095-                    Part = proj._pck.CreatePart(Uri, ExcelPackage.schemaVBASignature);
2096-                }
2097-            }
2098-            if (rel == null)
2099-            {
2100-                proj.Part.CreateRelationship(UriHelper.ResolvePartUri(proj.Uri, Uri), Packaging.TargetMode.Internal, schemaRelVbaSignature);               
2101-            }
2102-            var b = ms.ToArray();
2103-            Part.GetStream(FileMode.Create).Write(b, 0, b.Length);           
2104-        }
2105-
2106-        private X509Certificate2 GetCertFromStore(StoreLocation loc)
2107-        {
2108-            try
2109-            {
2110-                X509Store store = new X509Store(loc);
2111-                store.Open(OpenFlags.ReadOnly);
2112-                try
2113-                {
2114-                    var storeCert = store.Certificates.Find(
2115-                                    X509FindType.FindByThumbprint,
2116-                                    Certificate.Thumbprint,
2117-                                    true
2118-                                    ).OfType<X509Certificate2>().FirstOrDefault();
2119-                    return storeCert;
2120-                }
2121-                finally
2122-                {
2123-                    store.Close();
2124-                }
2125-            }
2126-            catch
2127-            {
2128-                return null;
2129-            }
2130-        }
2131-
2132-        private byte[] GetCertStore()
2133-        {
2134-            var ms = new MemoryStream();
2135-            var bw = new BinaryWriter(ms);
2136-
2137-            bw.Write((uint)0); //Version
2138-            bw.Write((uint)0x54524543); //fileType
2139-
2140-            //SerializedCertificateEntry
2141-            var certData = Certificate.RawData;
2142-            bw.Write((uint)0x20);
2143-            bw.Write((uint)1);
2144-            bw.Write((uint)certData.Length);
2145-            bw.Write(certData);
2146-
2147-            //EndElementMarkerEntry
2148-            bw.Write((uint)0);
2149-            bw.Write((ulong)0);
2150-
2151-            bw.Flush();
2152-            return ms.ToArray();
2153-        }
2154-
2155-        private void WriteProp(BinaryWriter bw, int id, byte[] data)
2156-        {
2157-            bw.Write((uint)id);
2158-            bw.Write((uint)1);
2159-            bw.Write((uint)data.Length);
2160-            bw.Write(data);
2161-        }
2162-        internal byte[] SignProject(ExcelVbaProject proj)
2163-        {
2164-            if (!Certificate.HasPrivateKey)
2165-            {
2166-                //throw (new InvalidOperationException("The certificate doesn't have a private key"));
2167-                Certificate = null;
2168-                return null;
2169-            }
2170-            var hash = GetContentHash(proj);
2171-
2172-            BinaryWriter bw = new BinaryWriter(new MemoryStream());
2173-            bw.Write((byte)0x30); //Constructed Type
2174-            bw.Write((byte)0x32); //Total length
2175-            bw.Write((byte)0x30); //Constructed Type
2176-            bw.Write((byte)0x0E); //Length SpcIndirectDataContent
2177-            bw.Write((byte)0x06); //Oid Tag Indentifier
2178-            bw.Write((byte)0x0A); //Lenght OId
2179-            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
2180-            bw.Write((byte)0x04);   //Octet String Tag Identifier
2181-            bw.Write((byte)0x00);   //Zero length
2182-
2183-            bw.Write((byte)0x30); //Constructed Type (DigestInfo)
2184-            bw.Write((byte)0x20); //Length DigestInfo
2185-            bw.Write((byte)0x30); //Constructed Type (Algorithm)
2186-            bw.Write((byte)0x0C); //length AlgorithmIdentifier
2187-            bw.Write((byte)0x06); //Oid Tag Indentifier
2188-            bw.Write((byte)0x08); //Lenght OId
2189-            bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5)
2190-            bw.Write((byte)0x05);   //Null type identifier
2191-            bw.Write((byte)0x00);   //Null length
2192-            bw.Write((byte)0x04);   //Octet String Identifier
2193-            bw.Write((byte)hash.Length);   //Hash length
2194-            bw.Write(hash);                //Content hash
2195-
2196-            ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray());
2197-            contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4";
2198-            Verifier = new SignedCms(contentInfo);
2199-            var signer = new CmsSigner(Certificate);
2200-            Verifier.ComputeSignature(signer, false);
2201-            return Verifier.Encode();
2202-        }
2203-
2204-        private byte[] GetContentHash(ExcelVbaProject proj)
2205-        {
2206-            //MS-OVBA 2.4.2
2207-            var enc = System.Text.Encoding.GetEncoding(proj.CodePage);
2208-            BinaryWriter bw = new BinaryWriter(new MemoryStream());
2209-            bw.Write(enc.GetBytes(proj.Name));
2210-            bw.Write(enc.GetBytes(proj.Constants));
2211-            foreach (var reference in proj.References)
2212-            {
2213-                if (reference.ReferenceRecordID == 0x0D)
2214-                {
2215-                    bw.Write((byte)0x7B);
2216-                }
2217-                if (reference.ReferenceRecordID == 0x0E)
2218-                {
2219-                    //var r = (ExcelVbaReferenceProject)reference;
2220-                    //BinaryWriter bwTemp = new BinaryWriter(new MemoryStream());
2221-                    //bwTemp.Write((uint)r.Libid.Length);
2222-                    //bwTemp.Write(enc.GetBytes(r.Libid));             
2223-                    //bwTemp.Write((uint)r.LibIdRelative.Length);
2224-                    //bwTemp.Write(enc.GetBytes(r.LibIdRelative));
2225-                    //bwTemp.Write(r.MajorVersion);
2226-                    //bwTemp.Write(r.MinorVersion);
2227-                    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.
2228-                    {
2229-                        if (b != 0)
2230-                        {
2231-                            bw.Write(b);
2232-                        }
2233-                        else
2234-                        {
2235-                            break;
2236-                        }
2237-                    }
2238-                }
2239-            }
2240-            foreach (var module in proj.Modules)
2241-            {
2242-                var lines = module.Code.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
2243-                foreach (var line in lines)
2244-                {
2245-                    if (!line.StartsWith("attribute", true, null))
2246-                    {
2247-                        bw.Write(enc.GetBytes(line));
2248-                    }
2249-                }
2250-            }
2251-            var buffer = (bw.BaseStream as MemoryStream).ToArray();
2252-            var hp = System.Security.Cryptography.MD5CryptoServiceProvider.Create();
2253-            return hp.ComputeHash(buffer);
2254-        }
2255-        /// <summary>
2256-        /// The certificate to sign the VBA project.
2257-        /// <remarks>
2258-        /// This certificate must have a private key.
2259-        /// 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).
2260-        /// </remarks>
2261-        /// </summary>
2262-        public X509Certificate2 Certificate { get; set; }
2263-        /// <summary>
2264-        /// The verifier
2265-        /// </summary>
2266-        public SignedCms Verifier { get; internal set; }
2267-#if !MONO
2268-        internal CompoundDocument Signature { get; set; }
2269-#endif
2270-        internal Packaging.ZipPackagePart Part { get; set; }
2271-        internal Uri Uri { get; private set; }
2272-    }
2273-}
Note: See TracBrowser for help on using the repository browser.