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); } }
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())); }
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); }
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); } }
/// <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())); }
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; } } }