| /******************************************************************************* | 
 |  * You may amend and distribute as you like, but don't remove this header! | 
 |  * | 
 |  * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. | 
 |  * See http://www.codeplex.com/EPPlus for details. | 
 |  * | 
 |  * Copyright (C) 2011  Jan Källman | 
 |  * | 
 |  * All code and executables are provided "as is" with no warranty either express or implied.  | 
 |  * The author accepts no liability for any damage or loss of business that this product may cause. | 
 |  * | 
 |  * If you want to understand this code have a look at the Office VBA File Format Structure Specification (MS-OVBA.PDF) or | 
 |  * http://msdn.microsoft.com/en-us/library/cc313094(v=office.12).aspx | 
 |  *  | 
 |  * * Code change notes: | 
 |  *  | 
 |  * Author							Change						Date | 
 |  ******************************************************************************* | 
 |  * Jan Källman		Added		26-MAR-2012 | 
 |  *******************************************************************************/ | 
 | using System; | 
 | using System.Collections.Generic; | 
 | using System.Globalization; | 
 | using System.Linq; | 
 | using System.Text; | 
 | using System.IO; | 
 | using OfficeOpenXml.Utils; | 
 | using System.Security.Cryptography.Pkcs; | 
 | using System.Security.Cryptography.X509Certificates; | 
 | using System.Security.Cryptography; | 
 | using System.Text.RegularExpressions; | 
 |  | 
 | namespace OfficeOpenXml.VBA | 
 | { | 
 |     /// <summary> | 
 |     /// Represents the VBA project part of the package | 
 |     /// </summary> | 
 |     public class ExcelVbaProject | 
 |     { | 
 |         const string schemaRelVba = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"; | 
 |         internal const string PartUri = @"/xl/vbaProject.bin"; | 
 |         #region Classes & Enums | 
 |         /// <summary> | 
 |         /// Type of system where the VBA project was created. | 
 |         /// </summary> | 
 |         public enum eSyskind | 
 |         { | 
 |             Win16 = 0, | 
 |             Win32 = 1, | 
 |             Macintosh = 2, | 
 |             Win64 = 3 | 
 |         } | 
 |  | 
 |         #endregion | 
 |         internal ExcelVbaProject(ExcelWorkbook wb) | 
 |         { | 
 |             _wb = wb; | 
 |             _pck = _wb._package.Package; | 
 |             References = new ExcelVbaReferenceCollection(); | 
 |             Modules = new ExcelVbaModuleCollection(this); | 
 |             var rel = _wb.Part.GetRelationshipsByType(schemaRelVba).FirstOrDefault(); | 
 |             if (rel != null) | 
 |             { | 
 |                 Uri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri); | 
 |                 Part = _pck.GetPart(Uri); | 
 | #if !MONO | 
 |                 GetProject();                 | 
 | #endif | 
 |             } | 
 |             else | 
 |             { | 
 |                 Lcid = 0; | 
 |                 Part = null; | 
 |             } | 
 |         } | 
 |         internal ExcelWorkbook _wb; | 
 |         internal Packaging.ZipPackage _pck; | 
 |         #region Dir Stream Properties | 
 |         /// <summary> | 
 |         /// System kind. Default Win32. | 
 |         /// </summary> | 
 |         public eSyskind SystemKind { get; set; } | 
 |         /// <summary> | 
 |         /// Name of the project | 
 |         /// </summary> | 
 |         public string Name { get; set; } | 
 |         /// <summary> | 
 |         /// A description of the project | 
 |         /// </summary> | 
 |         public string Description { get; set; } | 
 |         /// <summary> | 
 |         /// A helpfile | 
 |         /// </summary> | 
 |         public string HelpFile1 { get; set; } | 
 |         /// <summary> | 
 |         /// Secondary helpfile | 
 |         /// </summary> | 
 |         public string HelpFile2 { get; set; } | 
 |         /// <summary> | 
 |         /// Context if refering the helpfile | 
 |         /// </summary> | 
 |         public int HelpContextID { get; set; } | 
 |         /// <summary> | 
 |         /// Conditional compilation constants | 
 |         /// </summary> | 
 |         public string Constants { get; set; } | 
 |         /// <summary> | 
 |         /// Codepage for encoding. Default is current regional setting. | 
 |         /// </summary> | 
 |         public int CodePage { get; internal set; } | 
 |         internal int LibFlags { get; set; } | 
 |         internal int MajorVersion { get; set; } | 
 |         internal int MinorVersion { get; set; } | 
 |         internal int Lcid { get; set; } | 
 |         internal int LcidInvoke { get; set; } | 
 |         internal string ProjectID { get; set; } | 
 |         internal string ProjectStreamText { get; set; } | 
 |         /// <summary> | 
 |         /// Project references | 
 |         /// </summary>         | 
 |         public ExcelVbaReferenceCollection References { get; set; } | 
 |         /// <summary> | 
 |         /// Code Modules (Modules, classes, designer code) | 
 |         /// </summary> | 
 |         public ExcelVbaModuleCollection Modules { get; set; } | 
 |         ExcelVbaSignature _signature = null; | 
 |         /// <summary> | 
 |         /// The digital signature | 
 |         /// </summary> | 
 |         public ExcelVbaSignature Signature | 
 |         { | 
 |             get | 
 |             { | 
 |                 if (_signature == null) | 
 |                 { | 
 |                     _signature=new ExcelVbaSignature(Part); | 
 |                 } | 
 |                 return _signature; | 
 |             } | 
 |         } | 
 |         ExcelVbaProtection _protection=null; | 
 |         /// <summary> | 
 |         /// VBA protection  | 
 |         /// </summary> | 
 |         public ExcelVbaProtection Protection | 
 |         { | 
 |             get | 
 |             { | 
 |                 if (_protection == null) | 
 |                 { | 
 |                     _protection = new ExcelVbaProtection(this); | 
 |                 } | 
 |                 return _protection; | 
 |             } | 
 |         } | 
 |         #endregion | 
 | #if !MONO | 
 |         #region Read Project | 
 |         private void GetProject() | 
 |         { | 
 |  | 
 |             var stream = Part.GetStream(); | 
 |             byte[] vba; | 
 |             vba = new byte[stream.Length]; | 
 |             stream.Read(vba, 0, (int)stream.Length); | 
 |             Document = new CompoundDocument(vba); | 
 |  | 
 |             ReadDirStream(); | 
 |             ProjectStreamText = Encoding.GetEncoding(CodePage).GetString(Document.Storage.DataStreams["PROJECT"]); | 
 |             ReadModules(); | 
 |             ReadProjectProperties(); | 
 |         } | 
 |         private void ReadModules() | 
 |         { | 
 |             foreach (var modul in Modules) | 
 |             { | 
 |                 var stream = Document.Storage.SubStorage["VBA"].DataStreams[modul.streamName]; | 
 |                 var byCode = CompoundDocument.DecompressPart(stream, (int)modul.ModuleOffset); | 
 |                 string code = Encoding.GetEncoding(CodePage).GetString(byCode); | 
 |                 int pos=0; | 
 |                 while(pos+9<code.Length && code.Substring(pos,9)=="Attribute") | 
 |                 { | 
 |                     int linePos=code.IndexOf("\r\n",pos); | 
 |                     string[] lineSplit; | 
 |                     if(linePos>0) | 
 |                     { | 
 |                         lineSplit = code.Substring(pos + 9, linePos - pos - 9).Split('='); | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         lineSplit=code.Substring(pos+9).Split(new char[]{'='},1); | 
 |                     } | 
 |                     if (lineSplit.Length > 1) | 
 |                     { | 
 |                         lineSplit[1] = lineSplit[1].Trim(); | 
 |                         var attr =  | 
 |                             new ExcelVbaModuleAttribute() | 
 |                         { | 
 |                             Name = lineSplit[0].Trim(), | 
 |                             DataType = lineSplit[1].StartsWith("\"") ? eAttributeDataType.String : eAttributeDataType.NonString, | 
 |                             Value = lineSplit[1].StartsWith("\"") ? lineSplit[1].Substring(1, lineSplit[1].Length - 2) : lineSplit[1] | 
 |                         }; | 
 |                         modul.Attributes._list.Add(attr); | 
 |                     } | 
 |                     pos = linePos + 2; | 
 |                 } | 
 |                 modul.Code=code.Substring(pos); | 
 |             } | 
 |         } | 
 |  | 
 |         private void ReadProjectProperties() | 
 |         { | 
 |             _protection = new ExcelVbaProtection(this); | 
 |             string prevPackage = ""; | 
 |             var lines = Regex.Split(ProjectStreamText, "\r\n"); | 
 |             foreach (string line in lines) | 
 |             { | 
 |                 if (line.StartsWith("[")) | 
 |                 { | 
 |  | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     var split = line.Split('='); | 
 |                     if (split.Length > 1 && split[1].Length > 1 && split[1].StartsWith("\"")) //Remove any double qouates | 
 |                     { | 
 |                         split[1] = split[1].Substring(1, split[1].Length - 2); | 
 |                     } | 
 |                     switch (split[0]) | 
 |                     { | 
 |                         case "ID": | 
 |                             ProjectID = split[1]; | 
 |                             break; | 
 |                         case "Document": | 
 |                             string mn = split[1].Substring(0, split[1].IndexOf("/&H")); | 
 |                             Modules[mn].Type = eModuleType.Document; | 
 |                             break; | 
 |                         case "Package": | 
 |                             prevPackage = split[1]; | 
 |                             break; | 
 |                         case "BaseClass": | 
 |                             Modules[split[1]].Type = eModuleType.Designer; | 
 |                             Modules[split[1]].ClassID = prevPackage; | 
 |                             break; | 
 |                         case "Module": | 
 |                             Modules[split[1]].Type = eModuleType.Module; | 
 |                             break; | 
 |                         case "Class": | 
 |                             Modules[split[1]].Type = eModuleType.Class; | 
 |                             break; | 
 |                         case "HelpFile": | 
 |                         case "Name": | 
 |                         case "HelpContextID": | 
 |                         case "Description": | 
 |                         case "VersionCompatible32": | 
 |                             break; | 
 |                         //393222000" | 
 |                         case "CMG": | 
 |                             byte[] cmg = Decrypt(split[1]); | 
 |                             _protection.UserProtected = (cmg[0] & 1) != 0; | 
 |                             _protection.HostProtected = (cmg[0] & 2) != 0; | 
 |                             _protection.VbeProtected = (cmg[0] & 4) != 0; | 
 |                             break; | 
 |                         case "DPB": | 
 |                             byte[] dpb = Decrypt(split[1]); | 
 |                             if (dpb.Length >= 28) | 
 |                             { | 
 |                                 byte reserved = dpb[0]; | 
 |                                 var flags = new byte[3]; | 
 |                                 Array.Copy(dpb, 1, flags, 0, 3); | 
 |                                 var keyNoNulls = new byte[4]; | 
 |                                 _protection.PasswordKey = new byte[4]; | 
 |                                 Array.Copy(dpb, 4, keyNoNulls, 0, 4); | 
 |                                 var hashNoNulls = new byte[20]; | 
 |                                 _protection.PasswordHash = new byte[20]; | 
 |                                 Array.Copy(dpb, 8, hashNoNulls, 0, 20); | 
 |                                 //Handle 0x00 bitwise 2.4.4.3  | 
 |                                 for (int i = 0; i < 24; i++) | 
 |                                 { | 
 |                                     int bit = 128 >> (int)((i % 8)); | 
 |                                     if (i < 4) | 
 |                                     { | 
 |                                         if ((int)(flags[0] & bit) == 0) | 
 |                                         { | 
 |                                             _protection.PasswordKey[i] = 0; | 
 |                                         } | 
 |                                         else | 
 |                                         { | 
 |                                             _protection.PasswordKey[i] = keyNoNulls[i]; | 
 |                                         } | 
 |                                     } | 
 |                                     else | 
 |                                     { | 
 |                                         int flagIndex = (i - i % 8) / 8; | 
 |                                         if ((int)(flags[flagIndex] & bit) == 0) | 
 |                                         { | 
 |                                             _protection.PasswordHash[i - 4] = 0; | 
 |                                         } | 
 |                                         else | 
 |                                         { | 
 |                                             _protection.PasswordHash[i - 4] = hashNoNulls[i - 4]; | 
 |                                         } | 
 |                                     } | 
 |                                 } | 
 |                             } | 
 |                             break; | 
 |                         case "GC": | 
 |                             _protection.VisibilityState = Decrypt(split[1])[0] == 0xFF; | 
 |  | 
 |                             break; | 
 |                     } | 
 |                 } | 
 |             } | 
 |         } | 
 |  | 
 |         /// <summary> | 
 |         /// 2.4.3.3 Decryption | 
 |         /// </summary> | 
 |         /// <param name="value">Byte hex string</param> | 
 |         /// <returns>The decrypted value</returns> | 
 |         private byte[] Decrypt(string value) | 
 |         { | 
 |             byte[] enc = GetByte(value); | 
 |             byte[] dec = new byte[(value.Length - 1)]; | 
 |             byte seed, version, projKey, ignoredLength; | 
 |             seed = enc[0]; | 
 |             dec[0] = (byte)(enc[1] ^ seed); | 
 |             dec[1] = (byte)(enc[2] ^ seed); | 
 |             for (int i = 2; i < enc.Length - 1; i++) | 
 |             { | 
 |                 dec[i] = (byte)(enc[i + 1] ^ (enc[i - 1] + dec[i - 1])); | 
 |             } | 
 |             version = dec[0]; | 
 |             projKey = dec[1]; | 
 |             ignoredLength = (byte)((seed & 6) / 2); | 
 |             int datalength = BitConverter.ToInt32(dec, ignoredLength + 2); | 
 |             var data = new byte[datalength]; | 
 |             Array.Copy(dec, 6 + ignoredLength, data, 0, datalength); | 
 |             return data; | 
 |         } | 
 |         /// <summary> | 
 |         /// 2.4.3.2 Encryption | 
 |         /// </summary> | 
 |         /// <param name="value"></param> | 
 |         /// <returns>Byte hex string</returns> | 
 |         private string Encrypt(byte[] value) | 
 |         { | 
 |             byte[] seed = new byte[1]; | 
 |             var rn = RandomNumberGenerator.Create(); | 
 |             rn.GetBytes(seed); | 
 |             BinaryWriter br = new BinaryWriter(new MemoryStream()); | 
 |             byte[] enc = new byte[value.Length + 10]; | 
 |             enc[0] = seed[0]; | 
 |             enc[1] = (byte)(2 ^ seed[0]); | 
 |  | 
 |             byte projKey = 0; | 
 |  | 
 |             foreach (var c in ProjectID) | 
 |             { | 
 |                 projKey += (byte)c; | 
 |             } | 
 |             enc[2] = (byte)(projKey ^ seed[0]); | 
 |             var ignoredLength = (seed[0] & 6) / 2; | 
 |             for (int i = 0; i < ignoredLength; i++) | 
 |             { | 
 |                 br.Write(seed[0]); | 
 |             } | 
 |             br.Write(value.Length); | 
 |             br.Write(value); | 
 |  | 
 |             int pos = 3; | 
 |             byte pb = projKey; | 
 |             foreach (var b in ((MemoryStream)br.BaseStream).ToArray()) | 
 |             { | 
 |                 enc[pos] = (byte)(b ^ (enc[pos - 2] + pb)); | 
 |                 pos++; | 
 |                 pb = b; | 
 |             } | 
 |  | 
 |             return GetString(enc, pos - 1); | 
 |         } | 
 |         private string GetString(byte[] value, int max) | 
 |         { | 
 |             string ret = ""; | 
 |             for (int i = 0; i <= max; i++) | 
 |             { | 
 |                 if (value[i] < 16) | 
 |                 { | 
 |                     ret += "0" + value[i].ToString("x"); | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     ret += value[i].ToString("x"); | 
 |                 } | 
 |             } | 
 |             return ret.ToUpper(CultureInfo.InvariantCulture); | 
 |         } | 
 |         private byte[] GetByte(string value) | 
 |         { | 
 |             byte[] ret = new byte[value.Length / 2]; | 
 |             for (int i = 0; i < ret.Length; i++) | 
 |             { | 
 |                 ret[i] = byte.Parse(value.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier); | 
 |             } | 
 |             return ret; | 
 |         } | 
 |         private void ReadDirStream() | 
 |         { | 
 |             byte[] dir = CompoundDocument.DecompressPart(Document.Storage.SubStorage["VBA"].DataStreams["dir"]); | 
 |             MemoryStream ms = new MemoryStream(dir); | 
 |             BinaryReader br = new BinaryReader(ms); | 
 |             ExcelVbaReference currentRef = null; | 
 |             string referenceName = ""; | 
 |             ExcelVBAModule currentModule = null; | 
 |             bool terminate = false; | 
 |             while (br.BaseStream.Position < br.BaseStream.Length && terminate == false) | 
 |             { | 
 |                 ushort id = br.ReadUInt16(); | 
 |                 uint size = br.ReadUInt32(); | 
 |                 switch (id) | 
 |                 { | 
 |                     case 0x01: | 
 |                         SystemKind = (eSyskind)br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x02: | 
 |                         Lcid = (int)br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x03: | 
 |                         CodePage = (int)br.ReadUInt16(); | 
 |                         break; | 
 |                     case 0x04: | 
 |                         Name = GetString(br, size); | 
 |                         break; | 
 |                     case 0x05: | 
 |                         Description = GetUnicodeString(br, size); | 
 |                         break; | 
 |                     case 0x06: | 
 |                         HelpFile1 = GetString(br, size); | 
 |                         break; | 
 |                     case 0x3D: | 
 |                         HelpFile2 = GetString(br, size); | 
 |                         break; | 
 |                     case 0x07: | 
 |                         HelpContextID = (int)br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x08: | 
 |                         LibFlags = (int)br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x09: | 
 |                         MajorVersion = (int)br.ReadUInt32(); | 
 |                         MinorVersion = (int)br.ReadUInt16(); | 
 |                         break; | 
 |                     case 0x0C: | 
 |                         Constants = GetUnicodeString(br, size); | 
 |                         break; | 
 |                     case 0x0D: | 
 |                         uint sizeLibID = br.ReadUInt32(); | 
 |                         var regRef = new ExcelVbaReference(); | 
 |                         regRef.Name = referenceName; | 
 |                         regRef.ReferenceRecordID = id; | 
 |                         regRef.Libid = GetString(br, sizeLibID); | 
 |                         uint reserved1 = br.ReadUInt32(); | 
 |                         ushort reserved2 = br.ReadUInt16(); | 
 |                         References.Add(regRef); | 
 |                         break; | 
 |                     case 0x0E: | 
 |                         var projRef = new ExcelVbaReferenceProject(); | 
 |                         projRef.ReferenceRecordID = id; | 
 |                         projRef.Name = referenceName; | 
 |                         sizeLibID = br.ReadUInt32(); | 
 |                         projRef.Libid = GetString(br, sizeLibID); | 
 |                         sizeLibID = br.ReadUInt32(); | 
 |                         projRef.LibIdRelative = GetString(br, sizeLibID); | 
 |                         projRef.MajorVersion = br.ReadUInt32(); | 
 |                         projRef.MinorVersion = br.ReadUInt16(); | 
 |                         References.Add(projRef); | 
 |                         break; | 
 |                     case 0x0F: | 
 |                         ushort modualCount = br.ReadUInt16(); | 
 |                         break; | 
 |                     case 0x13: | 
 |                         ushort cookie = br.ReadUInt16(); | 
 |                         break; | 
 |                     case 0x14: | 
 |                         LcidInvoke = (int)br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x16: | 
 |                         referenceName = GetUnicodeString(br, size); | 
 |                         break; | 
 |                     case 0x19: | 
 |                         currentModule = new ExcelVBAModule(); | 
 |                         currentModule.Name = GetUnicodeString(br, size); | 
 |                         Modules.Add(currentModule); | 
 |                         break; | 
 |                     case 0x1A: | 
 |                         currentModule.streamName = GetUnicodeString(br, size); | 
 |                         break; | 
 |                     case 0x1C: | 
 |                         currentModule.Description = GetUnicodeString(br, size); | 
 |                         break; | 
 |                     case 0x1E: | 
 |                         currentModule.HelpContext = (int)br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x21: | 
 |                     case 0x22: | 
 |                         break; | 
 |                     case 0x2B:      //Modul Terminator | 
 |                         break; | 
 |                     case 0x2C: | 
 |                         currentModule.Cookie = br.ReadUInt16(); | 
 |                         break; | 
 |                     case 0x31: | 
 |                         currentModule.ModuleOffset = br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x10: | 
 |                         terminate = true; | 
 |                         break; | 
 |                     case 0x30: | 
 |                         var extRef = (ExcelVbaReferenceControl)currentRef; | 
 |                         var sizeExt = br.ReadUInt32(); | 
 |                         extRef.LibIdExternal = GetString(br, sizeExt); | 
 |  | 
 |                         uint reserved4 = br.ReadUInt32(); | 
 |                         ushort reserved5 = br.ReadUInt16(); | 
 |                         extRef.OriginalTypeLib = new Guid(br.ReadBytes(16)); | 
 |                         extRef.Cookie = br.ReadUInt32(); | 
 |                         break; | 
 |                     case 0x33: | 
 |                         currentRef = new ExcelVbaReferenceControl(); | 
 |                         currentRef.ReferenceRecordID = id; | 
 |                         currentRef.Name = referenceName; | 
 |                         currentRef.Libid = GetString(br, size); | 
 |                         References.Add(currentRef); | 
 |                         break; | 
 |                     case 0x2F: | 
 |                         var contrRef = (ExcelVbaReferenceControl)currentRef; | 
 |                         contrRef.ReferenceRecordID = id; | 
 |  | 
 |                         var sizeTwiddled = br.ReadUInt32(); | 
 |                         contrRef.LibIdTwiddled = GetString(br, sizeTwiddled); | 
 |                         var r1 = br.ReadUInt32(); | 
 |                         var r2 = br.ReadUInt16(); | 
 |  | 
 |                         break; | 
 |                     case 0x25: | 
 |                         currentModule.ReadOnly = true; | 
 |                         break; | 
 |                     case 0x28: | 
 |                         currentModule.Private = true; | 
 |                         break; | 
 |                     default: | 
 |                         break; | 
 |                 } | 
 |             } | 
 |         } | 
 |         #endregion | 
 |  | 
 |         #region Save Project | 
 |         internal void Save() | 
 |         { | 
 |             if (Validate()) | 
 |             { | 
 |                 CompoundDocument doc = new CompoundDocument(); | 
 |                 doc.Storage = new CompoundDocument.StoragePart(); | 
 |                 var store = new CompoundDocument.StoragePart(); | 
 |                 doc.Storage.SubStorage.Add("VBA", store); | 
 |  | 
 |                 store.DataStreams.Add("_VBA_PROJECT", CreateVBAProjectStream()); | 
 |                 store.DataStreams.Add("dir", CreateDirStream()); | 
 |                 foreach (var module in Modules) | 
 |                 { | 
 |                     store.DataStreams.Add(module.Name, CompoundDocument.CompressPart(Encoding.GetEncoding(CodePage).GetBytes(module.Attributes.GetAttributeText() + module.Code))); | 
 |                 } | 
 |  | 
 |                 //Copy streams from the template, if used. | 
 |                 if (Document != null) | 
 |                 { | 
 |                     foreach (var ss in Document.Storage.SubStorage) | 
 |                     { | 
 |                         if (ss.Key != "VBA") | 
 |                         { | 
 |                             doc.Storage.SubStorage.Add(ss.Key, ss.Value); | 
 |                         } | 
 |                     } | 
 |                     foreach (var s in Document.Storage.DataStreams) | 
 |                     { | 
 |                         if (s.Key != "dir" && s.Key != "PROJECT" && s.Key != "PROJECTwm") | 
 |                         { | 
 |                             doc.Storage.DataStreams.Add(s.Key, s.Value); | 
 |                         } | 
 |                     } | 
 |                 } | 
 |  | 
 |                 doc.Storage.DataStreams.Add("PROJECT", CreateProjectStream()); | 
 |                 doc.Storage.DataStreams.Add("PROJECTwm", CreateProjectwmStream()); | 
 |  | 
 |                 if (Part == null) | 
 |                 { | 
 |                     Uri = new Uri(PartUri, UriKind.Relative); | 
 |                     Part = _pck.CreatePart(Uri, ExcelPackage.schemaVBA); | 
 |                     var rel = _wb.Part.CreateRelationship(Uri, Packaging.TargetMode.Internal, schemaRelVba); | 
 |                 } | 
 |                 var vbaBuffer=doc.Save(); | 
 |                 var st = Part.GetStream(FileMode.Create); | 
 |                 st.Write(vbaBuffer, 0, vbaBuffer.Length); | 
 |                 st.Flush(); | 
 |                 //Save the digital signture | 
 |                 Signature.Save(this); | 
 |             } | 
 |         } | 
 |  | 
 |         private bool Validate() | 
 |         { | 
 |             Description = Description ?? ""; | 
 |             HelpFile1 = HelpFile1 ?? ""; | 
 |             HelpFile2 = HelpFile2 ?? ""; | 
 |             Constants = Constants ?? ""; | 
 |             return true; | 
 |         } | 
 |  | 
 |         /// <summary> | 
 |         /// MS-OVBA 2.3.4.1 | 
 |         /// </summary> | 
 |         /// <returns></returns> | 
 |         private byte[] CreateVBAProjectStream() | 
 |         { | 
 |             BinaryWriter bw = new BinaryWriter(new MemoryStream()); | 
 |             bw.Write((ushort)0x61CC); //Reserved1 | 
 |             bw.Write((ushort)0xFFFF); //Version | 
 |             bw.Write((byte)0x0); //Reserved3 | 
 |             bw.Write((ushort)0x0); //Reserved4 | 
 |             return ((MemoryStream)bw.BaseStream).ToArray(); | 
 |         } | 
 |         /// <summary> | 
 |         /// MS-OVBA 2.3.4.1 | 
 |         /// </summary> | 
 |         /// <returns></returns> | 
 |         private byte[] CreateDirStream() | 
 |         { | 
 |             BinaryWriter bw = new BinaryWriter(new MemoryStream()); | 
 |  | 
 |             /****** PROJECTINFORMATION Record ******/ | 
 |             bw.Write((ushort)1);        //ID | 
 |             bw.Write((uint)4);          //Size | 
 |             bw.Write((uint)SystemKind); //SysKind | 
 |  | 
 |             bw.Write((ushort)2);        //ID | 
 |             bw.Write((uint)4);          //Size | 
 |             bw.Write((uint)Lcid);       //Lcid | 
 |  | 
 |             bw.Write((ushort)0x14);     //ID | 
 |             bw.Write((uint)4);          //Size | 
 |             bw.Write((uint)LcidInvoke); //Lcid Invoke | 
 |  | 
 |             bw.Write((ushort)3);        //ID | 
 |             bw.Write((uint)2);          //Size | 
 |             bw.Write((ushort)CodePage);   //Codepage | 
 |  | 
 |             //ProjectName | 
 |             bw.Write((ushort)4);                                            //ID | 
 |             bw.Write((uint)Name.Length);                             //Size | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Name)); //Project Name | 
 |  | 
 |             //Description | 
 |             bw.Write((ushort)5);                                            //ID | 
 |             bw.Write((uint)Description.Length);                             //Size | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Description)); //Project Name | 
 |             bw.Write((ushort)0x40);                                           //ID | 
 |             bw.Write((uint)Description.Length*2);                           //Size | 
 |             bw.Write(Encoding.Unicode.GetBytes(Description));               //Project Description | 
 |  | 
 |             //Helpfiles | 
 |             bw.Write((ushort)6);                                           //ID | 
 |             bw.Write((uint)HelpFile1.Length);                              //Size | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile1));  //HelpFile1             | 
 |             bw.Write((ushort)0x3D);                                           //ID | 
 |             bw.Write((uint)HelpFile2.Length);                              //Size | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(HelpFile2));  //HelpFile2 | 
 |  | 
 |             //Help context id | 
 |             bw.Write((ushort)7);            //ID | 
 |             bw.Write((uint)4);              //Size | 
 |             bw.Write((uint)HelpContextID);  //Help context id | 
 |  | 
 |             //Libflags | 
 |             bw.Write((ushort)8);            //ID | 
 |             bw.Write((uint)4);              //Size | 
 |             bw.Write((uint)0);  //Help context id | 
 |  | 
 |             //Vba Version | 
 |             bw.Write((ushort)9);            //ID | 
 |             bw.Write((uint)4);              //Reserved | 
 |             bw.Write((uint)MajorVersion);   //Reserved | 
 |             bw.Write((ushort)MinorVersion); //Help context id | 
 |  | 
 |             //Constants | 
 |             bw.Write((ushort)0x0C);           //ID | 
 |             bw.Write((uint)Constants.Length);              //Size | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(Constants));              //Help context id | 
 |             bw.Write((ushort)0x3C);                                           //ID | 
 |             bw.Write((uint)Constants.Length/2);                              //Size | 
 |             bw.Write(Encoding.Unicode.GetBytes(Constants));  //HelpFile2 | 
 |  | 
 |             /****** PROJECTREFERENCES Record ******/ | 
 |             foreach (var reference in References) | 
 |             { | 
 |                 WriteNameReference(bw, reference); | 
 |  | 
 |                 if (reference.ReferenceRecordID == 0x2F) | 
 |                 { | 
 |                     WriteControlReference(bw, reference); | 
 |                 } | 
 |                 else if (reference.ReferenceRecordID == 0x33) | 
 |                 { | 
 |                     WriteOrginalReference(bw, reference); | 
 |                 } | 
 |                 else if (reference.ReferenceRecordID == 0x0D) | 
 |                 { | 
 |                     WriteRegisteredReference(bw, reference); | 
 |                 } | 
 |                 else if (reference.ReferenceRecordID == 0x0E) | 
 |                 { | 
 |                     WriteProjectReference(bw, reference); | 
 |                 } | 
 |             } | 
 |  | 
 |             bw.Write((ushort)0x0F); | 
 |             bw.Write((uint)0x02); | 
 |             bw.Write((ushort)Modules.Count); | 
 |             bw.Write((ushort)0x13); | 
 |             bw.Write((uint)0x02); | 
 |             bw.Write((ushort)0xFFFF); | 
 |  | 
 |             foreach (var module in Modules) | 
 |             { | 
 |                 WriteModuleRecord(bw, module); | 
 |             } | 
 |             bw.Write((ushort)0x10);             //Terminator | 
 |             bw.Write((uint)0);               | 
 |  | 
 |             return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray()); | 
 |         } | 
 |  | 
 |         private void WriteModuleRecord(BinaryWriter bw, ExcelVBAModule module) | 
 |         { | 
 |             bw.Write((ushort)0x19); | 
 |             bw.Write((uint)module.Name.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name));     //Name | 
 |  | 
 |             bw.Write((ushort)0x47); | 
 |             bw.Write((uint)module.Name.Length*2); | 
 |             bw.Write(Encoding.Unicode.GetBytes(module.Name));                   //Name | 
 |  | 
 |             bw.Write((ushort)0x1A); | 
 |             bw.Write((uint)module.Name.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name));     //Stream Name   | 
 |  | 
 |             bw.Write((ushort)0x32); | 
 |             bw.Write((uint)module.Name.Length*2); | 
 |             bw.Write(Encoding.Unicode.GetBytes(module.Name));                   //Stream Name | 
 |  | 
 |             module.Description = module.Description ?? ""; | 
 |             bw.Write((ushort)0x1C); | 
 |             bw.Write((uint)module.Description.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Description));     //Description | 
 |  | 
 |             bw.Write((ushort)0x48); | 
 |             bw.Write((uint)module.Description.Length*2); | 
 |             bw.Write(Encoding.Unicode.GetBytes(module.Description));                   //Description | 
 |  | 
 |             bw.Write((ushort)0x31); | 
 |             bw.Write((uint)4); | 
 |             bw.Write((uint)0);                              //Module Stream Offset (No PerformanceCache) | 
 |  | 
 |             bw.Write((ushort)0x1E); | 
 |             bw.Write((uint)4); | 
 |             bw.Write((uint)module.HelpContext);            //Help context ID | 
 |  | 
 |             bw.Write((ushort)0x2C); | 
 |             bw.Write((uint)2); | 
 |             bw.Write((ushort)0xFFFF);            //Help context ID | 
 |  | 
 |             bw.Write((ushort)(module.Type == eModuleType.Module ? 0x21 : 0x22)); | 
 |             bw.Write((uint)0); | 
 |  | 
 |             if (module.ReadOnly) | 
 |             { | 
 |                 bw.Write((ushort)0x25); | 
 |                 bw.Write((uint)0);              //Readonly | 
 |             } | 
 |  | 
 |             if (module.Private) | 
 |             { | 
 |                 bw.Write((ushort)0x28); | 
 |                 bw.Write((uint)0);              //Private | 
 |             } | 
 |  | 
 |             bw.Write((ushort)0x2B);             //Terminator | 
 |             bw.Write((uint)0);               | 
 |         } | 
 |  | 
 |         private void WriteNameReference(BinaryWriter bw, ExcelVbaReference reference) | 
 |         { | 
 |             //Name record | 
 |             bw.Write((ushort)0x16);                                             //ID | 
 |             bw.Write((uint)reference.Name.Length);                              //Size | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Name));  //HelpFile1 | 
 |             bw.Write((ushort)0x3E);                                             //ID | 
 |             bw.Write((uint)reference.Name.Length * 2);                            //Size | 
 |             bw.Write(Encoding.Unicode.GetBytes(reference.Name));                //HelpFile2 | 
 |         } | 
 |         private void WriteControlReference(BinaryWriter bw, ExcelVbaReference reference) | 
 |         { | 
 |             WriteOrginalReference(bw, reference); | 
 |  | 
 |             bw.Write((ushort)0x2F); | 
 |             var controlRef=(ExcelVbaReferenceControl)reference; | 
 |             bw.Write((uint)(4 + controlRef.LibIdTwiddled.Length + 4 + 2));    // Size of SizeOfLibidTwiddled, LibidTwiddled, Reserved1, and Reserved2. | 
 |             bw.Write((uint)controlRef.LibIdTwiddled.Length);                              //Size             | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdTwiddled));  //LibID | 
 |             bw.Write((uint)0);      //Reserved1 | 
 |             bw.Write((ushort)0);    //Reserved2 | 
 |             WriteNameReference(bw, reference);  //Name record again | 
 |             bw.Write((ushort)0x30); //Reserved3 | 
 |             bw.Write((uint)(4 + controlRef.LibIdExternal.Length + 4 + 2 + 16 + 4));    //Size of SizeOfLibidExtended, LibidExtended, Reserved4, Reserved5, OriginalTypeLib, and Cookie | 
 |             bw.Write((uint)controlRef.LibIdExternal.Length);                              //Size             | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(controlRef.LibIdExternal));  //LibID | 
 |             bw.Write((uint)0);      //Reserved4 | 
 |             bw.Write((ushort)0);    //Reserved5 | 
 |             bw.Write(controlRef.OriginalTypeLib.ToByteArray()); | 
 |             bw.Write((uint)controlRef.Cookie);      //Cookie | 
 |         } | 
 |  | 
 |         private void WriteOrginalReference(BinaryWriter bw, ExcelVbaReference reference) | 
 |         { | 
 |             bw.Write((ushort)0x33); | 
 |             bw.Write((uint)reference.Libid.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid));  //LibID | 
 |         } | 
 |         private void WriteProjectReference(BinaryWriter bw, ExcelVbaReference reference) | 
 |         { | 
 |             bw.Write((ushort)0x0E); | 
 |             var projRef = (ExcelVbaReferenceProject)reference; | 
 |             bw.Write((uint)(4 + projRef.Libid.Length + 4 + projRef.LibIdRelative.Length+4+2)); | 
 |             bw.Write((uint)projRef.Libid.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.Libid));  //LibAbsolute | 
 |             bw.Write((uint)projRef.LibIdRelative.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(projRef.LibIdRelative));  //LibIdRelative | 
 |             bw.Write(projRef.MajorVersion); | 
 |             bw.Write(projRef.MinorVersion); | 
 |         } | 
 |  | 
 |         private void WriteRegisteredReference(BinaryWriter bw, ExcelVbaReference reference) | 
 |         { | 
 |             bw.Write((ushort)0x0D); | 
 |             bw.Write((uint)(4+reference.Libid.Length+4+2)); | 
 |             bw.Write((uint)reference.Libid.Length); | 
 |             bw.Write(Encoding.GetEncoding(CodePage).GetBytes(reference.Libid));  //LibID             | 
 |             bw.Write((uint)0);      //Reserved1 | 
 |             bw.Write((ushort)0);    //Reserved2 | 
 |         } | 
 |  | 
 |         private byte[] CreateProjectwmStream() | 
 |         { | 
 |             BinaryWriter bw = new BinaryWriter(new MemoryStream()); | 
 |  | 
 |             foreach (var module in Modules) | 
 |             { | 
 |                 bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name));     //Name | 
 |                 bw.Write((byte)0); //Null | 
 |                 bw.Write(Encoding.Unicode.GetBytes(module.Name));                   //Name | 
 |                 bw.Write((ushort)0); //Null | 
 |             } | 
 |             bw.Write((ushort)0); //Null | 
 |             return CompoundDocument.CompressPart(((MemoryStream)bw.BaseStream).ToArray()); | 
 |         }        | 
 |         private byte[] CreateProjectStream() | 
 |         { | 
 |             StringBuilder sb = new StringBuilder(); | 
 |             sb.AppendFormat("ID=\"{0}\"\r\n", ProjectID); | 
 |             foreach(var module in Modules) | 
 |             { | 
 |                 if (module.Type == eModuleType.Document) | 
 |                 { | 
 |                     sb.AppendFormat("Document={0}/&H00000000\r\n", module.Name); | 
 |                 } | 
 |                 else if (module.Type == eModuleType.Module) | 
 |                 { | 
 |                     sb.AppendFormat("Module={0}\r\n", module.Name); | 
 |                 } | 
 |                 else if (module.Type == eModuleType.Class) | 
 |                 { | 
 |                     sb.AppendFormat("Class={0}\r\n", module.Name); | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     //Designer | 
 |                     sb.AppendFormat("Package={0}\r\n", module.ClassID); | 
 |                     sb.AppendFormat("BaseClass={0}\r\n", module.Name); | 
 |                 } | 
 |             } | 
 |             if (HelpFile1 != "") | 
 |             { | 
 |                 sb.AppendFormat("HelpFile={0}\r\n", HelpFile1); | 
 |             } | 
 |             sb.AppendFormat("Name=\"{0}\"\r\n", Name); | 
 |             sb.AppendFormat("HelpContextID={0}\r\n", HelpContextID); | 
 |  | 
 |             if (!string.IsNullOrEmpty(Description)) | 
 |             { | 
 |                 sb.AppendFormat("Description=\"{0}\"\r\n", Description); | 
 |             } | 
 |             sb.AppendFormat("VersionCompatible32=\"393222000\"\r\n"); | 
 |  | 
 |             sb.AppendFormat("CMG=\"{0}\"\r\n", WriteProtectionStat()); | 
 |             sb.AppendFormat("DPB=\"{0}\"\r\n", WritePassword()); | 
 |             sb.AppendFormat("GC=\"{0}\"\r\n\r\n", WriteVisibilityState()); | 
 |  | 
 |             sb.Append("[Host Extender Info]\r\n"); | 
 |             sb.Append("&H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000\r\n"); | 
 |             sb.Append("\r\n"); | 
 |             sb.Append("[Workspace]\r\n"); | 
 |             foreach(var module in Modules) | 
 |             { | 
 |                 sb.AppendFormat("{0}=0, 0, 0, 0, C \r\n",module.Name);               | 
 |             } | 
 |             string s = sb.ToString(); | 
 |             return Encoding.GetEncoding(CodePage).GetBytes(s); | 
 |         } | 
 |         private string WriteProtectionStat() | 
 |         { | 
 |             int stat=(_protection.UserProtected ? 1:0) |   | 
 |                      (_protection.HostProtected ? 2:0) | | 
 |                      (_protection.VbeProtected ? 4:0); | 
 |  | 
 |             return Encrypt(BitConverter.GetBytes(stat));     | 
 |         } | 
 |         private string WritePassword() | 
 |         { | 
 |             byte[] nullBits=new byte[3]; | 
 |             byte[] nullKey = new byte[4]; | 
 |             byte[] nullHash = new byte[20]; | 
 |             if (Protection.PasswordKey == null) | 
 |             { | 
 |                 return Encrypt(new byte[] { 0 }); | 
 |             } | 
 |             else | 
 |             { | 
 |                 Array.Copy(Protection.PasswordKey, nullKey, 4); | 
 |                 Array.Copy(Protection.PasswordHash, nullHash, 20); | 
 |  | 
 |                 //Set Null bits | 
 |                 for (int i = 0; i < 24; i++) | 
 |                 { | 
 |                     byte bit = (byte)(128 >> (int)((i % 8))); | 
 |                     if (i < 4) | 
 |                     { | 
 |                         if (nullKey[i] == 0) | 
 |                         { | 
 |                             nullKey[i] = 1; | 
 |                         } | 
 |                         else | 
 |                         { | 
 |                             nullBits[0] |= bit; | 
 |                         } | 
 |                     } | 
 |                     else | 
 |                     { | 
 |                         if (nullHash[i - 4] == 0) | 
 |                         { | 
 |                             nullHash[i - 4] = 1; | 
 |                         } | 
 |                         else | 
 |                         { | 
 |                             int byteIndex = (i - i % 8) / 8; | 
 |                             nullBits[byteIndex] |= bit; | 
 |                         } | 
 |                     } | 
 |                 } | 
 |                 //Write the Password Hash Data Structure (2.4.4.1) | 
 |                 BinaryWriter bw = new BinaryWriter(new MemoryStream()); | 
 |                 bw.Write((byte)0xFF); | 
 |                 bw.Write(nullBits); | 
 |                 bw.Write(nullKey); | 
 |                 bw.Write(nullHash); | 
 |                 bw.Write((byte)0); | 
 |                 return Encrypt(((MemoryStream)bw.BaseStream).ToArray()); | 
 |             } | 
 |         } | 
 |         private string WriteVisibilityState() | 
 |         { | 
 |             return Encrypt(new byte[] { (byte)(Protection.VisibilityState ? 0xFF : 0) });  | 
 |         } | 
 |         #endregion | 
 |         private string GetString(BinaryReader br, uint size) | 
 |         { | 
 |             return GetString(br, size, System.Text.Encoding.GetEncoding(CodePage)); | 
 |         } | 
 |         private string GetString(BinaryReader br, uint size, Encoding enc) | 
 |         { | 
 |             if (size > 0) | 
 |             { | 
 |                 byte[] byteTemp = new byte[size]; | 
 |                 byteTemp = br.ReadBytes((int)size); | 
 |                 return enc.GetString(byteTemp); | 
 |             } | 
 |             else | 
 |             { | 
 |                 return ""; | 
 |             } | 
 |         } | 
 |         private string GetUnicodeString(BinaryReader br, uint size) | 
 |         { | 
 |             string s = GetString(br, size); | 
 |             int reserved = br.ReadUInt16(); | 
 |             uint sizeUC = br.ReadUInt32(); | 
 |             string sUC = GetString(br, sizeUC, System.Text.Encoding.Unicode); | 
 |             return sUC.Length == 0 ? s : sUC; | 
 |         } | 
 |         internal CompoundDocument Document { get; set; } | 
 | #endif | 
 |         internal Packaging.ZipPackagePart Part { get; set; } | 
 |         internal Uri Uri { get; private set; } | 
 | #if !MONO | 
 |         /// <summary> | 
 |         /// Create a new VBA Project | 
 |         /// </summary> | 
 |         internal void Create() | 
 |         { | 
 |             if(Lcid>0) | 
 |             { | 
 |                 throw (new InvalidOperationException("Package already contains a VBAProject")); | 
 |             } | 
 |             ProjectID = "{5DD90D76-4904-47A2-AF0D-D69B4673604E}"; | 
 |             Name = "VBAProject"; | 
 |             SystemKind = eSyskind.Win32;            //Default | 
 |             Lcid = 1033;                            //English - United States | 
 |             LcidInvoke = 1033;                      //English - United States | 
 |             CodePage = Encoding.Default.CodePage; | 
 |             MajorVersion = 1361024421; | 
 |             MinorVersion = 6; | 
 |             HelpContextID = 0; | 
 |             Modules.Add(new ExcelVBAModule(_wb.CodeNameChange) { Name = "ThisWorkbook", Code = "", Attributes=GetDocumentAttributes("ThisWorkbook", "0{00020819-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 }); | 
 |             foreach (var sheet in _wb.Worksheets) | 
 |             { | 
 |                 var name = GetModuleNameFromWorksheet(sheet); | 
 |                 if (!Modules.Exists(name)) | 
 |                 { | 
 |                     Modules.Add(new ExcelVBAModule(sheet.CodeNameChange) { Name = name, Code = "", Attributes = GetDocumentAttributes(sheet.Name, "0{00020820-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 }); | 
 |                 } | 
 |             } | 
 |             _protection = new ExcelVbaProtection(this) { UserProtected = false, HostProtected = false, VbeProtected = false, VisibilityState = true }; | 
 |         } | 
 |  | 
 |         internal string GetModuleNameFromWorksheet(ExcelWorksheet sheet) | 
 |         { | 
 |             var name = sheet.Name; | 
 |             if (name.Any(c => c > 255) || this.Modules[name] != null) | 
 |             { | 
 |                 int i = sheet.PositionID; | 
 |                 name = "Sheet" + i.ToString(); | 
 |                 while (this.Modules[name] != null) | 
 |                 { | 
 |                     name = "Sheet" + (++i).ToString(); ; | 
 |                 } | 
 |             }             | 
 |             return name; | 
 |         } | 
 |         internal ExcelVbaModuleAttributesCollection GetDocumentAttributes(string name, string clsid) | 
 |         { | 
 |             var attr = new ExcelVbaModuleAttributesCollection(); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Name", Value = name, DataType = eAttributeDataType.String }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Base", Value = clsid, DataType = eAttributeDataType.String }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_GlobalNameSpace", Value = "False", DataType = eAttributeDataType.NonString }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Creatable", Value = "False", DataType = eAttributeDataType.NonString }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_PredeclaredId", Value = "True", DataType = eAttributeDataType.NonString }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Exposed", Value = "False", DataType = eAttributeDataType.NonString }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_TemplateDerived", Value = "False", DataType = eAttributeDataType.NonString }); | 
 |             attr._list.Add(new ExcelVbaModuleAttribute() { Name = "VB_Customizable", Value = "True", DataType = eAttributeDataType.NonString }); | 
 |  | 
 |             return attr; | 
 |         } | 
 |  | 
 |  | 
 |         //internal string GetBlankDocumentModule(string name, string clsid) | 
 |         //{ | 
 |         //    string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name); | 
 |         //    ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", clsid);  //Microsoft.Office.Interop.Excel.WorksheetClass | 
 |         //    ret += "Attribute VB_GlobalNameSpace = False\r\n"; | 
 |         //    ret += "Attribute VB_Creatable = False\r\n"; | 
 |         //    ret += "Attribute VB_PredeclaredId = True\r\n"; | 
 |         //    ret += "Attribute VB_Exposed = True\r\n"; | 
 |         //    ret += "Attribute VB_TemplateDerived = False\r\n"; | 
 |         //    ret += "Attribute VB_Customizable = True"; | 
 |         //    return ret; | 
 |         //} | 
 |         //internal string GetBlankModule(string name) | 
 |         //{ | 
 |         //    return string.Format("Attribute VB_Name = \"{0}\"\r\n", name); | 
 |         //} | 
 |         //internal string GetBlankClassModule(string name, bool exposed) | 
 |         //{ | 
 |         //    string ret=string.Format("Attribute VB_Name = \"{0}\"\r\n",name); | 
 |         //    ret += string.Format("Attribute VB_Base = \"{0}\"\r\n", "0{FCFB3D2A-A0FA-1068-A738-08002B3371B5}");   | 
 |         //    ret += "Attribute VB_GlobalNameSpace = False\r\n"; | 
 |         //    ret += "Attribute VB_Creatable = False\r\n"; | 
 |         //    ret += "Attribute VB_PredeclaredId = False\r\n"; | 
 |         //    ret += string.Format("Attribute VB_Exposed = {0}\r\n", exposed ? "True" : "False"); | 
 |         //    ret += "Attribute VB_TemplateDerived = False\r\n"; | 
 |         //    ret += "Attribute VB_Customizable = False\r\n"; | 
 |         //    return ret; | 
 |         //} | 
 | #endif | 
 |         /// <summary> | 
 |         /// Remove the project from the package | 
 |         /// </summary> | 
 |         public void Remove() | 
 |         { | 
 |             if (Part == null) return; | 
 |  | 
 |             foreach (var rel in Part.GetRelationships()) | 
 |             { | 
 |                 _pck.DeleteRelationship(rel.Id); | 
 |             } | 
 |             if (_pck.PartExists(Uri)) | 
 |             { | 
 |                 _pck.DeletePart(Uri); | 
 |             } | 
 |             Part = null; | 
 |             Modules.Clear(); | 
 |             References.Clear(); | 
 |             Lcid = 0; | 
 |             LcidInvoke = 0; | 
 |             CodePage = 0; | 
 |             MajorVersion = 0; | 
 |             MinorVersion = 0; | 
 |             HelpContextID = 0; | 
 |         } | 
 |         public override string ToString() | 
 |         { | 
 |             return Name; | 
 |         } | 
 |     } | 
 | } |