Exemple #1
0
        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, VBACompression.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 st = Part.GetStream(FileMode.Create);
                doc.Save(st);
                st.Flush();
                //Save the digital signture
                Signature.Save(this);
            }
        }
Exemple #2
0
        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(VBACompression.CompressPart(((MemoryStream)bw.BaseStream).ToArray()));
        }
Exemple #3
0
        public void Compression()
        {
            //Compression/Decompression
            string value = "#aaabcdefaaaaghijaaaaaklaaamnopqaaaaaaaaaaaarstuvwxyzaaa";

            byte[] compValue   = VBACompression.CompressPart(Encoding.GetEncoding(1252).GetBytes(value));
            string decompValue = Encoding.GetEncoding(1252).GetString(VBACompression.DecompressPart(compValue));

            Assert.AreEqual(value, decompValue);

            value = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

            compValue   = VBACompression.CompressPart(Encoding.GetEncoding(1252).GetBytes(value));
            decompValue = Encoding.GetEncoding(1252).GetString(VBACompression.DecompressPart(compValue));
            Assert.AreEqual(value, decompValue);
        }
Exemple #4
0
 private void ReadModules()
 {
     foreach (var modul in Modules)
     {
         var    stream = Document.Storage.SubStorage["VBA"].DataStreams[modul.streamName];
         var    byCode = VBACompression.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);
     }
 }
Exemple #5
0
        /// <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(VBACompression.CompressPart(((MemoryStream)bw.BaseStream).ToArray()));
        }
Exemple #6
0
        private void ReadDirStream()
        {
            byte[]            dir           = VBACompression.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;
                }
            }
        }