Example #1
0
        /// <summary>
        ///     Creates this object and sets all its properties
        /// </summary>
        /// <param name="storage">The OLE version 2.0 object as a <see cref="CFStorage" /></param>
        internal Ole10Native(CFStorage storage)
        {
            if (storage == null)
                throw new ArgumentNullException("storage");

            var ole10Native = storage.GetStream("\x0001Ole10Native");
            var compObj = storage.GetStream("\x0001CompObj");
            var compObjStream = new CompObjStream(compObj);

            AnsiUserType = compObjStream.AnsiUserType;
            StringFormat = compObjStream.StringFormat;
            ClipboardFormat = compObjStream.ClipboardFormat;

            switch (compObjStream.AnsiUserType)
            {
                case "OLE Package":
                    var ole10NativeSize = (int) ole10Native.Size - 4;
                    var data = ole10Native.GetData(4, ref ole10NativeSize);
                    var package = new Package(data);
                    Format = package.Format;
                    FileName = Path.GetFileName(package.FileName);
                    FilePath = package.FilePath;
                    NativeData = package.Data;
                    break;

                case "PBrush":
                case "Pakket":
                    // Ignore
                    break;

                default:
                    throw new OEObjectTypeNotSupported("Unsupported OleNative AnsiUserType '" +
                                                        compObjStream.AnsiUserType + "' found");
            }
        }
Example #2
0
        public void Test_DELETE_STREAM_2()
        {
            String filename = "MultipleStorage.cfs";

            CompoundFile cf  = new CompoundFile(filename);
            CFStorage    cfs = cf.RootStorage.GetStorage("MyStorage").GetStorage("AnotherStorage");

            cfs.Delete("AnotherStream");

            cf.Save(TestContext + "MultipleStorage_REMOVED_STREAM_2.cfs");

            cf.Close();
        }
Example #3
0
        /// <summary>
        ///     Writes the <see cref="Attachment" /> objects to the given <paramref name="rootStorage" />
        ///     and it will set all the needed properties
        /// </summary>
        /// <param name="rootStorage">The root <see cref="CFStorage" /></param>
        /// <returns>
        ///     Total size of the written <see cref="Attachment"/> objects and it's <see cref="Properties"/>
        /// </returns>
        internal long WriteToStorage(CFStorage rootStorage)
        {
            long size = 0;

            for (var index = 0; index < Count; index++)
            {
                var attachment = this[index];
                var storage    = rootStorage.AddStorage(PropertyTags.AttachmentStoragePrefix + index.ToString("X8").ToUpper());
                size += attachment.WriteProperties(storage, index);
            }

            return(size);
        }
Example #4
0
        public void Test_ENTRY_NAME_LENGTH()
        {
            //Thanks to Mark Bosold for bug fix and unit

            CompoundFile cf = new CompoundFile();

            // Cannot be equal.
            string maxCharactersStreamName = "1234567890123456789A12345678901"; // 31 chars
            string maxCharactersStorageName = "1234567890123456789012345678901"; // 31 chars

            // Try Storage entry name with max characters.
            Assert.IsNotNull(cf.RootStorage.AddStorage(maxCharactersStorageName));
            CFStorage strg = cf.RootStorage.GetStorage(maxCharactersStorageName);
            Assert.IsNotNull(strg);
            Assert.IsTrue(strg.Name == maxCharactersStorageName);


            // Try Stream entry name with max characters.
            Assert.IsNotNull(cf.RootStorage.AddStream(maxCharactersStreamName));
            CFStream strm = cf.RootStorage.GetStream(maxCharactersStreamName);
            Assert.IsNotNull(strm);
            Assert.IsTrue(strm.Name == maxCharactersStreamName);

            string tooManyCharactersEntryName = "12345678901234567890123456789012"; // 32 chars

            try
            {
                // Try Storage entry name with too many characters.
                cf.RootStorage.AddStorage(tooManyCharactersEntryName);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is CFException);
            }

            try
            {
                // Try Stream entry name with too many characters.
                cf.RootStorage.AddStream(tooManyCharactersEntryName);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex is CFException);
            }

            cf.Save("EntryNameLength");
            cf.Close();
        }
        private CFStorage GetStorage(CFStorage cfstorage, string storagename)
        {
            CFStorage storage = null;

            try
            {
                storage = cfstorage.GetStorage(storagename);
            }
            catch (Exception)
            {
            }

            return(storage);
        }
        private CFStream GetStream(CFStorage cfstorage, string streamname)
        {
            CFStream stream = null;

            try
            {
                stream = cfstorage.GetStream(streamname);
            }
            catch (Exception)
            {
            }

            return(stream);
        }
Example #7
0
        /// <summary>
        /// This will save the complete tree from the given <paramref name="storage"/> to a new <see cref="CompoundFile"/>
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="fileName">The filename with path for the new compound file</param>
        internal static string SaveStorageTreeToCompoundFile(CFStorage storage, string fileName)
        {
            Logger.WriteToLog($"Saving storage tree to compound file '{fileName}'");

            fileName = FileManager.FileExistsMakeNew(fileName);

            using (var compoundFile = new CompoundFile())
            {
                GetStorageChain(compoundFile.RootStorage, storage);
                compoundFile.Save(fileName);
            }

            return(fileName);
        }
Example #8
0
        private static void LoadMappings(Table table, CFStorage gameStorage)
        {
            var name = "Mappings0";

            gameStorage.TryGetStream(name, out var citStream);
            if (citStream != null)
            {
                using (var stream = new MemoryStream(citStream.GetData()))
                    using (var reader = new BinaryReader(stream))
                    {
                        table.Mappings = new Mappings.Mappings(reader, name);
                    }
            }
        }
Example #9
0
        public static CFStream GetStream(ref CompoundFile cf, string path, string name)
        {
            List <string> pathList = null;

            if (path != "%Root_Entry%")
            {
                pathList = path.Split(new char[]
                {
                    '/'
                }).ToList <string>();
            }
            CFStorage rootStorage = cf.RootStorage;

            return(CFUtil.GetStorage(pathList, ref rootStorage).GetStream(name));
        }
Example #10
0
        /// <summary>
        ///     Creates this object and reads all the <see cref="EntryStreamItem" /> objects from
        ///     the given <paramref name="storage"/>
        /// </summary>
        /// <param name="storage">The <see cref="CFStorage"/> that containts the <see cref="PropertyTags.EntryStream"/></param>
        internal EntryStream(CFStorage storage)
        {
            if (!storage.TryGetStream(PropertyTags.EntryStream, out var stream))
            {
                stream = storage.AddStream(PropertyTags.EntryStream);
            }

            using (var memoryStream = new MemoryStream(stream.GetData()))
                using (var binaryReader = new BinaryReader(memoryStream))
                    while (!binaryReader.Eos())
                    {
                        var entryStreamItem = new EntryStreamItem(binaryReader);
                        Add(entryStreamItem);
                    }
        }
Example #11
0
 public static CFStorage GetStorage(List <string> pathList, ref CFStorage storage)
 {
     if (pathList == null || pathList[0] == "")
     {
         return(storage);
     }
     if (pathList.Count <string>() > 1)
     {
         int    index       = pathList.Count <string>() - 1;
         string storageName = pathList[index];
         pathList.RemoveAt(index);
         return(CFUtil.GetStorage(pathList, ref storage).GetStorage(storageName));
     }
     return(storage.GetStorage(pathList[0]));
 }
Example #12
0
        public void Test_CREATE_STORAGE_WITH_CREATION_DATE()
        {
            const String STORAGE_NAME = "NewStorage1";
            CompoundFile cf           = new CompoundFile();

            CFStorage st = cf.RootStorage.AddStorage(STORAGE_NAME);

            st.CreationDate = DateTime.Now;

            Assert.IsNotNull(st);
            Assert.AreEqual(STORAGE_NAME, st.Name, false);

            cf.Save("ProvaData.cfs");
            cf.Close();
        }
Example #13
0
        internal void Write(CFStorage storage, string streamName)
        {
            var stream = storage.TryGetStream(streamName) ?? storage.AddStream(streamName);

            using (var memoryStream = new MemoryStream())
                using (var binaryWriter = new BinaryWriter(memoryStream))
                {
                    foreach (var entryStreamItem in this)
                    {
                        entryStreamItem.Write(binaryWriter);
                    }

                    stream.SetData(memoryStream.ToArray());
                }
        }
Example #14
0
        public void Test_DELETE_DIRECTORY()
        {
            String       FILENAME = "MultipleStorage2.cfs";
            CompoundFile cf       = new CompoundFile(FILENAME, CFSUpdateMode.ReadOnly, CFSConfiguration.Default);

            CFStorage st = cf.RootStorage.GetStorage("MyStorage");

            Assert.IsNotNull(st);

            st.Delete("AnotherStorage");

            cf.Save("MultipleStorage_Delete.cfs");

            cf.Close();
        }
Example #15
0
        /// <summary>
        /// Writes the library data from the current file which contains the PCB library
        /// header information parameters and also a list of the existing components.
        /// </summary>
        /// <param name="library"></param>
        private void WriteLibraryData(CFStorage library)
        {
            library.GetOrAddStream("Data").Write(writer =>
            {
                var parameters = Data.Header.ExportToParameters();
                WriteBlock(writer, w => WriteParameters(w, parameters));

                writer.Write(Data.Items.Count);
                foreach (var component in Data.Items)
                {
                    WriteStringBlock(writer, component.Pattern);
                    WriteFootprint(component);
                }
            });
        }
Example #16
0
        /// <summary>
        ///     Writes all the <see cref="EntryStreamItem"/>'s as a <see cref="CFStream" /> to the
        ///     given <paramref name="storage" />
        /// </summary>
        /// <param name="storage">The <see cref="CFStorage" /></param>
        internal void Write(CFStorage storage)
        {
            var stream = storage.GetStream(PropertyTags.EntryStream);

            using (var memoryStream = new MemoryStream())
                using (var binaryWriter = new BinaryWriter(memoryStream))
                {
                    foreach (var entryStreamItem in this)
                    {
                        entryStreamItem.Write(binaryWriter);
                    }

                    stream.SetData(memoryStream.ToArray());
                }
        }
Example #17
0
        /// <summary>
        ///     Writes all the <see cref="Guid"/>'s as a <see cref="CFStream" /> to the
        ///     given <paramref name="storage" />
        /// </summary>
        /// <param name="storage">The <see cref="CFStorage" /></param>
        internal void Write(CFStorage storage)
        {
            var stream = storage.GetStream(PropertyTags.GuidStream);

            using (var memoryStream = new MemoryStream())
                using (var binaryWriter = new BinaryWriter(memoryStream))
                {
                    foreach (var guid in this)
                    {
                        binaryWriter.Write(guid.ToByteArray());
                    }

                    stream.SetData(memoryStream.ToArray());
                }
        }
Example #18
0
        public void Test_FIX_BUG_GH_14()
        {
            String filename       = "MyFile.dat";
            String storageName    = "MyStorage";
            String streamName     = "MyStream";
            int    BUFFER_SIZE    = 800 * Mb;
            int    iterationCount = 3;
            int    streamCount    = 3;

            CompoundFile compoundFileInit = new CompoundFile(CFSVersion.Ver_4, CFSConfiguration.Default);

            compoundFileInit.Save(filename);
            compoundFileInit.Close();

            CompoundFile compoundFile = new CompoundFile(filename, CFSUpdateMode.Update, CFSConfiguration.Default);
            CFStorage    st           = compoundFile.RootStorage.AddStorage(storageName);
            byte         b            = 0X0A;

            for (int streamId = 0; streamId < streamCount; ++streamId)
            {
                CFStream sm = st.AddStream(streamName + streamId);
                for (int iteration = 0; iteration < iterationCount; ++iteration)
                {
                    sm.Append(Helpers.GetBuffer(BUFFER_SIZE, b));
                    compoundFile.Commit();
                }

                b++;
            }
            compoundFile.Close();

            compoundFile = new CompoundFile(filename, CFSUpdateMode.ReadOnly, CFSConfiguration.Default);
            byte[] testBuffer = new byte[100];
            byte   t          = 0x0A;

            for (int streamId = 0; streamId < streamCount; ++streamId)
            {
                compoundFile.RootStorage.GetStorage(storageName).GetStream(streamName + streamId).Read(testBuffer, BUFFER_SIZE / 2, 100);
                Assert.IsTrue(testBuffer.All(g => g == t));
                compoundFile.RootStorage.GetStorage(storageName).GetStream(streamName + streamId).Read(testBuffer, BUFFER_SIZE - 101, 100);
                Assert.IsTrue(testBuffer.All(g => g == t));
                compoundFile.RootStorage.GetStorage(storageName).GetStream(streamName + streamId).Read(testBuffer, 0, 100);
                Assert.IsTrue(testBuffer.All(g => g == t));
                t++;
            }

            compoundFile.Close();
        }
Example #19
0
        public void Test_VISIT_STORAGE()
        {
            String FILENAME = "testVisiting.xls";

            // Remove...
            if (File.Exists(FILENAME))
            {
                File.Delete(FILENAME);
            }

            //Create...

            CompoundFile ncf = new CompoundFile();

            CFStorage l1 = ncf.RootStorage.AddStorage("Storage Level 1");

            l1.AddStream("l1ns1");
            l1.AddStream("l1ns2");
            l1.AddStream("l1ns3");

            CFStorage l2 = l1.AddStorage("Storage Level 2");

            l2.AddStream("l2ns1");
            l2.AddStream("l2ns2");

            ncf.Save(FILENAME);
            ncf.Close();


            // Read...

            CompoundFile cf = new CompoundFile(FILENAME);

            FileStream output = new FileStream("reportVisit.txt", FileMode.Create);
            TextWriter sw     = new StreamWriter(output);

            Console.SetOut(sw);

            Action <CFItem> va = delegate(CFItem target)
            {
                sw.WriteLine(target.Name);
            };

            cf.RootStorage.VisitEntries(va, true);

            cf.Close();
            sw.Close();
        }
Example #20
0
 private void CopyStorage(CFStorage source, CFStorage dest)
 {
     source.VisitEntries(i =>
     {
         if (i.IsStorage)
         {
             CopyStorage((CFStorage)i, dest.AddStorage(i.Name));
         }
         else if (i.IsStream)
         {
             var newStream  = dest.AddStream(i.Name);
             var currStream = (CFStream)i;
             newStream.SetData(currStream.GetData());
         }
     }, false);
 }
Example #21
0
        /// <summary>
        ///     Writes all <see cref="Property">properties</see> either as a <see cref="CFStream"/> or as a collection in
        ///     a <see cref="PropertyTags.PropertiesStreamName"/> stream to the given <paramref name="storage"/>, this depends
        ///     on the <see cref="PropertyType"/>
        /// </summary>
        /// <remarks>
        ///     See the <see cref="Properties"/> class it's <see cref="Properties.WriteProperties"/> method for the logic
        ///     that is used to determine this
        /// </remarks>
        /// <param name="storage">The <see cref="CFStorage"/></param>
        /// <returns>
        ///     Total size of the written <see cref="Recipient"/> object and it's <see cref="Properties"/>
        /// </returns>
        internal long WriteProperties(CFStorage storage)
        {
            var propertiesStream = new RecipientProperties();

            propertiesStream.AddProperty(PropertyTags.PR_ROWID, RowId);
            propertiesStream.AddProperty(PropertyTags.PR_ENTRYID, Mapi.GenerateEntryId());
            propertiesStream.AddProperty(PropertyTags.PR_INSTANCE_KEY, Mapi.GenerateInstanceKey());
            propertiesStream.AddProperty(PropertyTags.PR_RECIPIENT_TYPE, RecipientType);
            propertiesStream.AddProperty(PropertyTags.PR_ADDRTYPE_W, AddressTypeString);
            propertiesStream.AddProperty(PropertyTags.PR_EMAIL_ADDRESS_W, Email);
            propertiesStream.AddProperty(PropertyTags.PR_OBJECT_TYPE, ObjectType);
            propertiesStream.AddProperty(PropertyTags.PR_DISPLAY_TYPE, DisplayType);
            propertiesStream.AddProperty(PropertyTags.PR_DISPLAY_NAME_W, DisplayName);
            propertiesStream.AddProperty(PropertyTags.PR_SEARCH_KEY, Mapi.GenerateSearchKey(AddressTypeString, Email));
            return(propertiesStream.WriteProperties(storage));
        }
Example #22
0
        /// <summary>
        /// Reads the library data from the current file which contains the PCB library
        /// header information parameters and also a list of the existing components.
        /// </summary>
        /// <param name="library"></param>
        private void ReadLibraryData(CFStorage library)
        {
            using (var reader = library.GetStream("Data").GetBinaryReader())
            {
                var parameters = ReadBlock(reader, size => ReadParameters(reader, size));
                Data.Header.ImportFromParameters(parameters);

                var footprintCount = reader.ReadUInt32();
                for (var i = 0; i < footprintCount; ++i)
                {
                    var refName    = ReadStringBlock(reader);
                    var sectionKey = GetSectionKeyFromRefName(refName);
                    Data.Items.Add(ReadFootprint(sectionKey));
                }
            }
        }
Example #23
0
        public VPXFile(string filename)
        {
            _cf = new CompoundFile(filename, CFSUpdateMode.ReadOnly, CFSConfiguration.Default);
            CFStorage gameStg = _cf.RootStorage.GetStorage("GameStg");
            UInt32    version = new VPXReader(gameStg.GetStream("Version")).ReadUInt32();

            void visitor(CFItem item)
            {
                if (item.Name.StartsWith("Image") && item is CFStream stream)
                {
                    ReadImage(stream, true);
                }
            }

            gameStg.VisitEntries(visitor, true);
        }
Example #24
0
 /// <summary>
 /// Adds a complete stream to the hash data.
 /// </summary>
 /// <param name="hashBuf">Current data to hash</param>
 /// <param name="streamName">Stream to hash</param>
 /// <param name="stg">Storage of the stream</param>
 private void AddStream(ICollection <byte[]> hashBuf, string streamName, CFStorage stg)
 {
     try {
         var stream = stg.GetStream(streamName);
         if (stream != null)
         {
             var data = stream.GetData();
             hashBuf.Add(data);
         }
     } catch (CFItemNotFound) {
         _logger.Warn("Skipping non-existent Stream {0}.", streamName);
     } catch (Exception e) {
         _logger.Error(e, "Error reading data!");
         _crashManager.Report(e, "vpt");
     }
 }
Example #25
0
 /// <summary>
 /// Reads the component parameter information.
 /// </summary>
 /// <param name="componentStorage">Component footprint storage key.</param>
 /// <param name="component">Component instance where the parameters will be imported into.</param>
 private void ReadFootprintParameters(CFStorage componentStorage, PcbComponent component)
 {
     BeginContext("Parameters");
     try
     {
         using (var reader = componentStorage.GetStream("Parameters").GetBinaryReader())
         {
             var parameters = ReadBlock(reader, size => ReadParameters(reader, size));
             component.ImportFromParameters(parameters);
         }
     }
     finally
     {
         EndContext();
     }
 }
        /// <summary>
        ///     Creates this object and sets all its properties
        /// </summary>
        /// <param name="storage">The OLE version 2.0 object as a <see cref="CFStorage" /></param>
        internal Ole10Native(CFStorage storage)
        {
            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }

            var ole10Native   = storage.GetStream("\x0001Ole10Native");
            var compObj       = storage.GetStream("\x0001CompObj");
            var compObjStream = new CompObjStream(compObj);

            AnsiUserType    = compObjStream.AnsiUserType;
            StringFormat    = compObjStream.StringFormat;
            ClipboardFormat = compObjStream.ClipboardFormat;

            switch (compObjStream.AnsiUserType)
            {
            case "OLE Package":
                var olePackageSize = (int)ole10Native.Size - 4;
                var olePackageData = new byte[olePackageSize];
                ole10Native.Read(olePackageData, 4, olePackageSize);
                var package = new Package(olePackageData);
                Format     = package.Format;
                FileName   = Path.GetFileName(package.FileName);
                FilePath   = package.FilePath;
                NativeData = package.Data;
                break;

            case "PBrush":
                var pbBrushSize = (int)ole10Native.Size - 4;
                var pbBrushData = new byte[pbBrushSize];
                ole10Native.Read(pbBrushData, 4, pbBrushSize);
                FileName   = "Embedded PBrush image.bmp";
                Format     = OleFormat.File;
                NativeData = pbBrushData;
                break;

            case "Pakket":
                // Ignore
                break;

            default:
                throw new OEObjectTypeNotSupported("Unsupported OleNative AnsiUserType '" +
                                                   compObjStream.AnsiUserType + "' found");
            }
        }
Example #27
0
        public void AddToCompoundFile(CompoundFile cf)
        {
            CFStorage projectStorage = cf.RootStorage.AddStorage("_VBA_PROJECT_CUR");
            CFStorage vbaStorage     = projectStorage.AddStorage("VBA");

            AddStreamToStorage(projectStorage, this.ProjectWmStream);
            AddStreamToStorage(projectStorage, this.ProjectStream);

            AddStreamToStorage(vbaStorage, this.ThisWorkbookStream);
            AddStreamToStorage(vbaStorage, this.VbaProjectStream);
            AddStreamToStorage(vbaStorage, this.dirStream);

            foreach (var modStream in ModuleStreams)
            {
                AddStreamToStorage(vbaStorage, modStream);
            }
        }
 private static void LoadCollections(FileTableContainer tableContainer, CFStorage storage)
 {
     for (var i = 0; i < tableContainer.NumCollections; i++)
     {
         var collectionName = $"Collection{i}";
         storage.TryGetStream(collectionName, out var collectionStream);
         if (collectionStream == null)
         {
             Logger.Warn("Could not find stream {0}, skipping.", collectionName);
             continue;
         }
         using (var stream = new MemoryStream(collectionStream.GetData()))
             using (var reader = new BinaryReader(stream)) {
                 tableContainer.Collections.Add(new CollectionData(reader, collectionName));
             }
     }
 }
Example #29
0
        private void ReadUniqueIdPrimitiveInformation(CFStorage componentStorage, PcbComponent component)
        {
            if (!componentStorage.TryGetStorage("UniqueIdPrimitiveInformation", out var uniqueIdPrimitiveInformation))
            {
                return;
            }

            BeginContext("UniqueIdPrimitiveInformation");
            try
            {
                var recordCount = ReadHeader(uniqueIdPrimitiveInformation);

                using (var reader = uniqueIdPrimitiveInformation.GetStream("Data").GetBinaryReader())
                {
                    uint actualRecordCount = 0;
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        var parameters        = ReadBlock(reader, size => ReadParameters(reader, size));
                        var primitiveIndex    = parameters["PRIMITIVEINDEX"].AsIntOrDefault();
                        var primitiveObjectId = parameters["PRIMITIVEOBJECTID"].AsStringOrDefault();
                        var uniqueId          = parameters["UNIQUEID"].AsStringOrDefault();

                        if (!CheckValue("PRIMITIVEINDEX < Primitives.Count", primitiveIndex < component.Primitives.Count, true))
                        {
                            return;
                        }

                        var primitive = component.Primitives[primitiveIndex];

                        if (!CheckValue(nameof(primitiveObjectId), primitiveObjectId, primitive.ObjectId.ToString()))
                        {
                            return;
                        }

                        primitive.UniqueId = uniqueId;
                        actualRecordCount++;
                    }
                    AssertValue(nameof(actualRecordCount), actualRecordCount, recordCount);
                }
            }
            finally
            {
                EndContext();
            }
        }
Example #30
0
        /// <summary>
        ///     Creates this object and sets all it's properties
        /// </summary>
        internal Message()
        {
            CompoundFile = new CompoundFile();

            // In the preceding figure, the "__nameid_version1.0" named property mapping storage contains the 
            // three streams  used to provide a mapping from property ID to property name 
            // ("__substg1.0_00020102", "__substg1.0_00030102", and "__substg1.0_00040102") and various other 
            // streams that provide a mapping from property names to property IDs.
            _nameIdStorage = CompoundFile.RootStorage.TryGetStorage(PropertyTags.NameIdStorage) ??
                             CompoundFile.RootStorage.AddStorage(PropertyTags.NameIdStorage);

            var entryStream = _nameIdStorage.AddStream(PropertyTags.EntryStream);
            entryStream.SetData(new byte[0]);
            var stringStream = _nameIdStorage.AddStream(PropertyTags.StringStream);
            stringStream.SetData(new byte[0]);
            var guidStream = _nameIdStorage.AddStream(PropertyTags.GuidStream);
            guidStream.SetData(new byte[0]);
        }
 private static void LoadCollections(Table table, CFStorage storage)
 {
     for (var i = 0; i < table.Data.NumCollections; i++)
     {
         var collectionName = $"Collection{i}";
         storage.TryGetStream(collectionName, out var collectionStream);
         if (collectionStream == null)
         {
             Logger.Warn("Could not find stream {0}, skipping.", collectionName);
             continue;
         }
         using (var stream = new MemoryStream(collectionStream.GetData()))
             using (var reader = new BinaryReader(stream)) {
                 var collection = new Collection.Collection(reader, collectionName);
                 table.Collections[collection.Name.ToLower()] = collection;
             }
     }
 }
        /// <summary>
        ///     Load compound file from an existing stream.
        /// </summary>
        /// <param name="stream">Stream to load compound file from</param>
        private void Load(Stream stream)
        {
            try
            {
                _header = new Header();
                _directoryEntries = new List<IDirectoryEntry>();

                SourceStream = stream;

                _header.Read(stream);

                var numberOfSectors = Ceiling(((stream.Length - GetSectorSize())/(double) GetSectorSize()));

                if (stream.Length > 0x7FFFFF0)
                    TransactionLockAllocated = true;

                _sectors = new SectorCollection();
                for (var i = 0; i < numberOfSectors; i++)
                    _sectors.Add(null);

                LoadDirectories();

                RootStorage = new CFStorage(this, _directoryEntries[0]);
            }
            catch (Exception)
            {
                if (stream != null)
                    stream.Close();

                throw;
            }
        }
        /// <summary>
        ///     Create a blank, version 3 compound file.
        ///     Sector recycle is turned off to achieve the best reading/writing
        ///     performance in most common scenarios.
        /// </summary>
        /// <example>
        ///     <code>
        ///  
        ///      byte[] b = new byte[10000];
        ///      for (int i = 0; i &lt; 10000; i++)
        ///      {
        ///          b[i % 120] = (byte)i;
        ///      }
        /// 
        ///      CompoundFile cf = new CompoundFile();
        ///      CFStream myStream = cf.RootStorage.AddStream("MyStream");
        /// 
        ///      Assert.IsNotNull(myStream);
        ///      myStream.SetData(b);
        ///      cf.Save("MyCompoundFile.cfs");
        ///      cf.Close();
        ///      
        ///  </code>
        /// </example>
        public CompoundFile()
        {
            _header = new Header();
            _sectorRecycle = false;

            _difatSectorFATEntriesCount = (GetSectorSize()/4) - 1;
            _fatSectorEntriesCount = (GetSectorSize()/4);

            //Root --
            RootStorage = new CFStorage(this);

            RootStorage.DirEntry.SetEntryName("Root Entry");
            RootStorage.DirEntry.StgType = StgType.StgRoot;
        }
        /// <summary>
        ///     Create a new, blank, compound file.
        /// </summary>
        /// <param name="cfsVersion">Use a specific Compound File Version to set 512 or 4096 bytes sectors</param>
        /// <param name="sectorRecycle">If true, recycle unused sectors</param>
        /// <example>
        ///     <code>
        ///  
        ///      byte[] b = new byte[10000];
        ///      for (int i = 0; i &lt; 10000; i++)
        ///      {
        ///          b[i % 120] = (byte)i;
        ///      }
        /// 
        ///      CompoundFile cf = new CompoundFile(CFSVersion.Ver_4, true, true);
        ///      CFStream myStream = cf.RootStorage.AddStream("MyStream");
        /// 
        ///      Assert.IsNotNull(myStream);
        ///      myStream.SetData(b);
        ///      cf.Save("MyCompoundFile.cfs");
        ///      cf.Close();
        ///      
        ///  </code>
        /// </example>
        /// <remarks>
        ///     Sector recycling reduces data writing performances but avoids space wasting in scenarios with frequently
        ///     data manipulation of the same streams. The new compound file is open in Update mode.
        /// </remarks>
        public CompoundFile(CFSVersion cfsVersion, bool sectorRecycle)
        {
            _header = new Header((ushort) cfsVersion);
            _sectorRecycle = sectorRecycle;

            _difatSectorFATEntriesCount = (GetSectorSize()/4) - 1;
            _fatSectorEntriesCount = (GetSectorSize()/4);

            //Root --
            RootStorage = new CFStorage(this);

            RootStorage.DirEntry.SetEntryName("Root Entry");
            RootStorage.DirEntry.StgType = StgType.StgRoot;
        }
Example #35
0
 /// <summary>
 /// Returns the complete tree with all the <see cref="CFStorage"/> and <see cref="CFStream"/> children
 /// </summary>
 /// <param name="rootStorage"></param>
 /// <param name="storage"></param>
 private static void GetStorageChain(CFStorage rootStorage, CFStorage storage)
 {
     foreach (var child in storage.Children)
     {
         if (child.IsStorage)
         {
             var newRootStorage = rootStorage.AddStorage(child.Name);
             GetStorageChain(newRootStorage, child as CFStorage);
         }
         else if (child.IsStream)
         {
             var childStream = child as CFStream;
             if (childStream == null) continue;
             var stream = rootStorage.AddStream(child.Name);
             var bytes = childStream.GetData();
             stream.SetData(bytes);
         }
     }
 }
Example #36
0
        /// <summary>
        /// This will save the complete tree from the given <paramref name="storage"/> to a new <see cref="CompoundFile"/>
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="fileName">The filename with path for the new compound file</param>
        internal static string SaveStorageTreeToCompoundFile(CFStorage storage, string fileName)
        {
            fileName = FileManager.FileExistsMakeNew(fileName);

            using (var compoundFile = new CompoundFile())
            {
                GetStorageChain(compoundFile.RootStorage, storage);
                compoundFile.Save(fileName);
            }

            return fileName;
        }
Example #37
0
        /// <summary>
        /// This method will extract and save the data from the given <see cref="storage"/> node to the <see cref="outputFolder"/>
        /// </summary>
        /// <param name="storage">The <see cref="CFStorage"/> node</param>
        /// <param name="outputFolder">The outputFolder</param>
        /// <param name="fileName">The fileName to use, null when the fileName is unknown</param>
        /// <returns></returns>
        /// <exception cref="OEFileIsPasswordProtected">Raised when a WordDocument, WorkBook or PowerPoint Document stream is password protected</exception>
        public static string SaveFromStorageNode(CFStorage storage, string outputFolder, string fileName)
        {
            if (storage.ExistsStream("CONTENTS"))
            {
                var contents = storage.GetStream("CONTENTS");
                if (contents.Size <= 0) return null;
                if (string.IsNullOrWhiteSpace(fileName)) fileName = DefaultEmbeddedObjectName;
                return SaveByteArrayToFile(contents.GetData(), Path.Combine(outputFolder, fileName));
            }
            
            if (storage.ExistsStream("Package"))
            {
                var package = storage.GetStream("Package");
                if (package.Size <= 0) return null;
                if (string.IsNullOrWhiteSpace(fileName)) fileName = DefaultEmbeddedObjectName;
                return SaveByteArrayToFile(package.GetData(), Path.Combine(outputFolder, fileName));
            }

            if (storage.ExistsStream("EmbeddedOdf"))
            {
                // The embedded object is an Embedded ODF file
                var package = storage.GetStream("EmbeddedOdf");
                if (package.Size <= 0) return null;
                if (string.IsNullOrWhiteSpace(fileName)) fileName = DefaultEmbeddedObjectName;
                return SaveByteArrayToFile(package.GetData(), Path.Combine(outputFolder, fileName));
            }

            if (storage.ExistsStream("\x0001Ole10Native"))
            {
                var ole10Native = new Ole10Native(storage);
                return ole10Native.Format == OleFormat.File
                    ? SaveByteArrayToFile(ole10Native.NativeData, Path.Combine(outputFolder, ole10Native.FileName))
                    : null;
            }

            if (storage.ExistsStream("WordDocument"))
            {
                // The embedded object is a Word file
                if (string.IsNullOrWhiteSpace(fileName)) fileName = "Embedded Word document.doc";
                return SaveStorageTreeToCompoundFile(storage, Path.Combine(outputFolder, fileName));
            }
            
            if (storage.ExistsStream("Workbook"))
            {
                // The embedded object is an Excel file   
                if (string.IsNullOrWhiteSpace(fileName)) fileName = "Embedded Excel document.xls";
                Excel.SetWorkbookVisibility(storage);
                return SaveStorageTreeToCompoundFile(storage, Path.Combine(outputFolder, fileName));
            }
            
            if (storage.ExistsStream("PowerPoint Document"))
            {
                // The embedded object is a PowerPoint file
                if (string.IsNullOrWhiteSpace(fileName)) fileName = "Embedded PowerPoint document.ppt";
                return SaveStorageTreeToCompoundFile(storage, Path.Combine(outputFolder, fileName));
            }
            
            return null;
        }
Example #38
0
 /// <summary>
 /// This method will extract and save the data from the given <see cref="storage"/> node to the <see cref="outputFolder"/>
 /// </summary>
 /// <param name="storage">The <see cref="CFStorage"/> node</param>
 /// <param name="outputFolder">The outputFolder</param>
 /// <returns></returns>
 /// <exception cref="OEFileIsPasswordProtected">Raised when a WordDocument, WorkBook or PowerPoint Document stream is password protected</exception>
 internal static string SaveFromStorageNode(CFStorage storage, string outputFolder)
 {
     return SaveFromStorageNode(storage, outputFolder, null);
 }
Example #39
0
        /// <summary>
        /// When a Excel document is embedded in for example a Word document the Workbook
        /// is set to hidden. Don't know why Microsoft does this but they do. To solve this
        /// problem we seek the WINDOW1 record in the BOF record of the stream. In there a
        /// gbit structure is located. The first bit in this structure controls the visibility
        /// of the workbook, so we check if this bit is set to 1 (hidden) en is so set it to 0.
        /// Normally a Workbook stream only contains one WINDOW record but when it is embedded
        /// it will contain 2 or more records.
        /// </summary>
        /// <param name="rootStorage">The <see cref="CFStorage">Root storage</see> of a <see cref="CompoundFile"/></param>
        /// <exception cref="OEFileIsCorrupt">Raised when the <paramref name="rootStorage"/> does not have a Workbook stream</exception>
        public static void SetWorkbookVisibility(CFStorage rootStorage)
        {
            if (!rootStorage.ExistsStream("WorkBook"))
                throw new OEFileIsCorrupt("Could not check workbook visibility because the WorkBook stream is not present");

            try
            {
                var stream = rootStorage.GetStream("WorkBook") as CFStream;
                if (stream == null) return;

                var bytes = stream.GetData();

                using (var memoryStream = new MemoryStream(bytes))
                using (var binaryReader = new BinaryReader(memoryStream))
                {
                    // Get the record type, at the beginning of the stream this should always be the BOF
                    var recordType = binaryReader.ReadUInt16();
                    var recordLength = binaryReader.ReadUInt16();

                    // Something seems to be wrong, we would expect a BOF but for some reason it isn't 
                    if (recordType != 0x809)
                        throw new OEFileIsCorrupt("The file is corrupt");

                    binaryReader.BaseStream.Position += recordLength;

                    while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length)
                    {
                        recordType = binaryReader.ReadUInt16();
                        recordLength = binaryReader.ReadUInt16();

                        // Window1 record (0x3D)
                        if (recordType == 0x3D)
                        {
                            // ReSharper disable UnusedVariable
                            var xWn = binaryReader.ReadUInt16();
                            var yWn = binaryReader.ReadUInt16();
                            var dxWn = binaryReader.ReadUInt16();
                            var dyWn = binaryReader.ReadUInt16();
                            // ReSharper restore UnusedVariable

                            // The grbit contains the bit that hides the sheet
                            var grbit = binaryReader.ReadBytes(2);
                            var bitArray = new BitArray(grbit);

                            // When the bit is set then unset it (bitArray.Get(0) == true)
                            if (bitArray.Get(0))
                            {
                                bitArray.Set(0, false);

                                // Copy the byte back into the stream, 2 positions back so that we overwrite the old bytes
                                bitArray.CopyTo(bytes, (int)binaryReader.BaseStream.Position - 2);
                            }

                            break;
                        }
                        binaryReader.BaseStream.Position += recordLength;
                    }
                }

                stream.SetData(bytes);
            }
            catch (Exception exception)
            {
                throw new OEFileIsCorrupt(
                    "Could not check workbook visibility because the file seems to be corrupt", exception);
            }
            
        }