diff -Nru openmcdf-1.5.2/OpenMcdf.xml openmcdf-1.5.4/OpenMcdf.xml --- openmcdf-1.5.2/OpenMcdf.xml 2011-05-05 18:40:28.000000000 +0000 +++ openmcdf-1.5.4/OpenMcdf.xml 2012-12-09 11:34:36.000000000 +0000 @@ -429,6 +429,36 @@ + + + Load an existing compound file. + + Compound file to read from + If true, recycle unused sectors + Select the update mode of the underlying data file + If true, overwrite with zeros unallocated sectors + If true, no CFCorruptedFileException + will be thrown even if corrupted file is loaded. Please note that this option is could pose a potential security threat + + + String srcFilename = "data_YOU_CAN_CHANGE.xls"; + + CompoundFile cf = new CompoundFile(srcFilename, UpdateMode.Update, true, true, true); + + + Random r = new Random(); + + byte[] buffer = GetBuffer(r.Next(3, 4095), 0x0A); + + cf.RootStorage.AddStream("MyStream").SetData(buffer); + + //This will persist data to the underlying media. + cf.Commit(); + cf.Close(); + + + + Load an existing compound file. @@ -457,6 +487,36 @@ Raised when trying to open a non-seekable stream Raised stream is null + + + Load an existing compound file. + + A stream containing a compound file to read + If true, recycle unused sectors + Select the update mode of the underlying data file + If true, overwrite with zeros unallocated sectors + If true, openMcdf will try to ignore invalid references or format in order to load a possibly corrupted file anyway + The 'noValidationEcxception' parameter could possibly lead to security issues so it's recommanded to use it only on trusted sources + + + + String filename = "reportREAD.xls"; + + FileStream fs = new FileStream(filename, FileMode.Open); + CompoundFile cf = new CompoundFile(fs, UpdateMode.ReadOnly, false, false, false, true); + CFStream foundStream = cf.RootStorage.GetStream("Workbook"); + + byte[] temp = foundStream.GetData(); //if 'reportRead.xls' is corrupted, openMcdf will try to lad it anyway [noValidationException set true] + + Assert.IsNotNull(temp); + + cf.Close(); + + + + Raised when trying to open a non-seekable stream + Raised stream is null + Load an existing compound file from a stream. @@ -679,6 +739,18 @@ If true, method has been called from User code, if false it's been called from .net runtime + + + Get a list of all entries with a given name contained in the document. + + Name of entries to retrive + A list of name-matching entries + This function is aimed to speed up entity lookup in + flat-structure files (only one or little more known entries) + without the performance penalty related to entities hierarchy constraints. + There is no implied hierarchy in the returned list. + + Compress free space by removing unallocated sectors from compound file @@ -1240,6 +1312,14 @@ the same storage or sub-storage. + + + Raised when trying to load a Compound File with invalid, corrupted or mismatched fields (4.1 - specifications) + + + This exception is NOT raised when Compound file has been opened with NO_VALIDATION_EXCEPTION option. + + Represents a binary tree. This class provides access to the Root of the tree. The developer diff -Nru openmcdf-1.5.2/Release notes.txt openmcdf-1.5.4/Release notes.txt --- openmcdf-1.5.2/Release notes.txt 2011-05-05 18:45:52.000000000 +0000 +++ openmcdf-1.5.4/Release notes.txt 2012-12-09 12:26:54.000000000 +0000 @@ -1,3 +1,16 @@ +ver 1.5.4 +FIXED: In particular conditions, an opened file could be left opened after a loading exception +FIXED: Circular references of corrupted files could lead to stack overflows +FIXED: Enanched standard compliance: corrupted file loading defaults to abort operation. +ADD: Version property +ADD: New overloaded constructors to force the load of possibly corrrupted files. + +--------- +ver 1.5.3 +ADD: 'GetAllNamedEntries' Method to access structured files without tree-loading performance penalties +ADD: New hex editor for stuctured storage explorer sample application + +--------- ver 1.5.2 FIXED: Math error in sector number recognition caused exception when reading some streams FIXED: Saving twice caused OutOfMemoryException diff -Nru openmcdf-1.5.2/debian/changelog openmcdf-1.5.4/debian/changelog --- openmcdf-1.5.2/debian/changelog 2012-05-04 08:00:42.000000000 +0000 +++ openmcdf-1.5.4/debian/changelog 2013-04-08 09:02:44.000000000 +0000 @@ -1,3 +1,10 @@ +openmcdf (1.5.4-1) unstable; urgency=low + + * New upstream: 1.5.4 + - Use Hexbox for hexadecimal viewing + + -- Mathieu Malaterre Mon, 08 Apr 2013 11:02:15 +0200 + openmcdf (1.5.2-1) unstable; urgency=low * Initial release. (Closes: #647886) diff -Nru openmcdf-1.5.2/debian/control openmcdf-1.5.4/debian/control --- openmcdf-1.5.2/debian/control 2012-05-03 15:15:26.000000000 +0000 +++ openmcdf-1.5.4/debian/control 2013-04-08 09:03:02.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: Debian CLI Applications Team Uploaders: Mathieu Malaterre Build-Depends: debhelper (>= 8), cli-common-dev (>= 0.5.7) -Build-Depends-Indep: mono-devel, mono-xbuild +Build-Depends-Indep: mono-devel, mono-xbuild, libhexbox1.5-cil Standards-Version: 3.9.3 Homepage: http://openmcdf.sourceforge.net/ Vcs-Git: git://git.debian.org/pkg-cli-apps/packages/openmcdf.git diff -Nru openmcdf-1.5.2/debian/patches/fixhexboxloc.patch openmcdf-1.5.4/debian/patches/fixhexboxloc.patch --- openmcdf-1.5.2/debian/patches/fixhexboxloc.patch 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/debian/patches/fixhexboxloc.patch 2013-04-08 08:56:22.000000000 +0000 @@ -0,0 +1,13 @@ +Index: openmcdf/src/TESTOpenMCDF/StructuredStorageExplorer.csproj +=================================================================== +--- openmcdf.orig/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2013-04-08 10:56:10.742333571 +0200 ++++ openmcdf/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2013-04-08 10:56:20.074333464 +0200 +@@ -32,7 +32,7 @@ + 4 + + +- ++ + + + diff -Nru openmcdf-1.5.2/debian/patches/hexbox150.patch openmcdf-1.5.4/debian/patches/hexbox150.patch --- openmcdf-1.5.2/debian/patches/hexbox150.patch 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/debian/patches/hexbox150.patch 2013-04-08 08:50:50.000000000 +0000 @@ -0,0 +1,17 @@ +Description: HexBox 1.5.0 changed the API +Author: Mathieu Malaterre +Forwarded: https://sourceforge.net/p/openmcdf/bugs/13/ + +Index: openmcdf/src/TESTOpenMCDF/MainForm.Designer.cs +=================================================================== +--- openmcdf.orig/src/TESTOpenMCDF/MainForm.Designer.cs 2013-04-08 08:48:37.222338677 +0000 ++++ openmcdf/src/TESTOpenMCDF/MainForm.Designer.cs 2013-04-08 08:48:37.182338674 +0000 +@@ -264,7 +264,7 @@ + this.hexEditor.BackColor = System.Drawing.Color.WhiteSmoke; + this.hexEditor.Dock = System.Windows.Forms.DockStyle.Fill; + this.hexEditor.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); +- this.hexEditor.LineInfoForeColor = System.Drawing.Color.Empty; ++ this.hexEditor.InfoForeColor = System.Drawing.Color.Empty; + this.hexEditor.LineInfoVisible = true; + this.hexEditor.Location = new System.Drawing.Point(0, 0); + this.hexEditor.Name = "hexEditor"; diff -Nru openmcdf-1.5.2/debian/patches/series openmcdf-1.5.4/debian/patches/series --- openmcdf-1.5.2/debian/patches/series 2012-05-04 07:58:26.000000000 +0000 +++ openmcdf-1.5.4/debian/patches/series 2013-04-08 08:56:00.000000000 +0000 @@ -1 +1,3 @@ use_default_framework.patch +hexbox150.patch +fixhexboxloc.patch diff -Nru openmcdf-1.5.2/debian/patches/use_default_framework.patch openmcdf-1.5.4/debian/patches/use_default_framework.patch --- openmcdf-1.5.2/debian/patches/use_default_framework.patch 2012-05-04 07:59:48.000000000 +0000 +++ openmcdf-1.5.4/debian/patches/use_default_framework.patch 2013-04-08 08:49:45.000000000 +0000 @@ -1,7 +1,10 @@ +Description: Need to use default debian version +Author: Mathieu Malaterre + Index: openmcdf/src/OLECompoundFileStorage/OpenMcdf.csproj =================================================================== ---- openmcdf.orig/src/OLECompoundFileStorage/OpenMcdf.csproj 2012-05-04 09:58:32.241541230 +0200 -+++ openmcdf/src/OLECompoundFileStorage/OpenMcdf.csproj 2012-05-04 09:59:28.773539188 +0200 +--- openmcdf.orig/src/OLECompoundFileStorage/OpenMcdf.csproj 2013-04-08 08:48:32.078338733 +0000 ++++ openmcdf/src/OLECompoundFileStorage/OpenMcdf.csproj 2013-04-08 08:48:32.054338733 +0000 @@ -1,5 +1,5 @@  - @@ -26,8 +29,8 @@ + Index: openmcdf/src/OleCfsMemoryTest/OpenMcdfMemTest.csproj =================================================================== ---- openmcdf.orig/src/OleCfsMemoryTest/OpenMcdfMemTest.csproj 2012-05-04 09:58:40.993540913 +0200 -+++ openmcdf/src/OleCfsMemoryTest/OpenMcdfMemTest.csproj 2012-05-04 09:59:36.817538898 +0200 +--- openmcdf.orig/src/OleCfsMemoryTest/OpenMcdfMemTest.csproj 2013-04-08 08:48:32.078338733 +0000 ++++ openmcdf/src/OleCfsMemoryTest/OpenMcdfMemTest.csproj 2013-04-08 08:48:32.054338733 +0000 @@ -1,5 +1,5 @@  - @@ -52,8 +55,8 @@ + Index: openmcdf/src/TESTOpenMCDF/StructuredStorageExplorer.csproj =================================================================== ---- openmcdf.orig/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2012-05-04 09:58:47.601540672 +0200 -+++ openmcdf/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2012-05-04 09:59:45.097538597 +0200 +--- openmcdf.orig/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2013-04-08 08:48:32.078338733 +0000 ++++ openmcdf/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2013-04-08 08:48:32.058338733 +0000 @@ -1,5 +1,5 @@  - @@ -69,7 +72,7 @@ 512 -@@ -92,4 +91,4 @@ +@@ -98,4 +97,4 @@ --> @@ -78,8 +81,8 @@ + Index: openmcdf/src/OLECFSTest/OpenMcdfTest.csproj =================================================================== ---- openmcdf.orig/src/OLECFSTest/OpenMcdfTest.csproj 2012-05-04 09:58:59.701540236 +0200 -+++ openmcdf/src/OLECFSTest/OpenMcdfTest.csproj 2012-05-04 09:59:17.893539581 +0200 +--- openmcdf.orig/src/OLECFSTest/OpenMcdfTest.csproj 2013-04-08 08:48:32.078338733 +0000 ++++ openmcdf/src/OLECFSTest/OpenMcdfTest.csproj 2013-04-08 08:48:32.058338733 +0000 @@ -1,4 +1,4 @@ - + diff -Nru openmcdf-1.5.2/debian/rules openmcdf-1.5.4/debian/rules --- openmcdf-1.5.2/debian/rules 2012-05-03 15:15:06.000000000 +0000 +++ openmcdf-1.5.4/debian/rules 2013-04-08 08:55:09.000000000 +0000 @@ -9,21 +9,26 @@ xbuild /target:StructuredStorageExplorer $(CURDIR)/src/OpenMcdf.sln xbuild /target:OpenMcdf $(CURDIR)/src/OpenMcdf.sln -override_dh_auto_clean: +override_dh_clean: # OpenMcdf target: - rm -f src/OLECompoundFileStorage/obj/Debug/OpenMcdf.dll - rm -f src/OLECompoundFileStorage/obj/Debug/OpenMcdf.dll.mdb - rm -f src/OLECompoundFileStorage/bin/Debug/OpenMcdf.dll - rm -f src/OLECompoundFileStorage/bin/Debug/OpenMcdf.dll.mdb + dh_clean src/OLECompoundFileStorage/obj/Debug/OpenMcdf.dll + dh_clean src/OLECompoundFileStorage/obj/Debug/OpenMcdf.dll.mdb + dh_clean src/OLECompoundFileStorage/bin/Debug/OpenMcdf.dll + dh_clean src/OLECompoundFileStorage/bin/Debug/OpenMcdf.dll.mdb # StructuredStorageExplorer target: - rm -f src/TESTOpenMCDF/obj/Debug/StucturedStorageExplorer.exe - rm -f src/TESTOpenMCDF/obj/Debug/StructuredStorageExplorer.MainForm.resources - rm -f src/TESTOpenMCDF/obj/Debug/StucturedStorageExplorer.exe.mdb - rm -f src/TESTOpenMCDF/bin/Debug/OpenMcdf.dll - rm -f src/TESTOpenMCDF/bin/Debug/OpenMcdf.dll.mdb - rm -f src/TESTOpenMCDF/bin/Debug/StucturedStorageExplorer.exe - rm -f src/TESTOpenMCDF/bin/Debug/StucturedStorageExplorer.exe.mdb - rm -f src/TESTOpenMCDF/obj/Debug/StructuredStorageExplorer.Properties.Resources.resources + dh_clean src/TESTOpenMCDF/obj/Debug/StucturedStorageExplorer.exe + dh_clean src/TESTOpenMCDF/obj/Debug/StructuredStorageExplorer.MainForm.resources + dh_clean src/TESTOpenMCDF/obj/Debug/StucturedStorageExplorer.exe.mdb + dh_clean src/TESTOpenMCDF/bin/Debug/OpenMcdf.dll + dh_clean src/TESTOpenMCDF/bin/Debug/OpenMcdf.dll.mdb + dh_clean src/TESTOpenMCDF/bin/Debug/StucturedStorageExplorer.exe + dh_clean src/TESTOpenMCDF/bin/Debug/StucturedStorageExplorer.exe.mdb + dh_clean src/TESTOpenMCDF/obj/Debug/StructuredStorageExplorer.Properties.Resources.resources + # + dh_clean src/OLECompoundFileStorage/bin/Debug/OpenMcdf.xml + dh_clean src/OLECompoundFileStorage/obj/Debug/OpenMcdf.csproj.FilesWrittenAbsolute.txt + dh_clean src/TESTOpenMCDF/bin/Debug/StucturedStorageExplorer.exe.config + dh_clean src/TESTOpenMCDF/obj/Debug/StructuredStorageExplorer.csproj.FilesWrittenAbsolute.txt override_dh_install: dh_install src/TESTOpenMCDF/bin/Debug/StucturedStorageExplorer.exe usr/lib/OpenMCDF @@ -52,7 +57,7 @@ #get-orig-source: # uscan --verbose --force-download --repack --rename -VER_FULL = 1.5.2 +VER_FULL = 1.5.4 UPSTREAM_SRC = "OpenMCDF $(VER_FULL)" UPSTREAM_SRC_DIR = "OpenMcdf $(VER_FULL)" @@ -60,7 +65,7 @@ DEBIAN_SRC_TAR = openmcdf_$(VER_FULL).orig.tar.gz get-orig-source: - wget -c http://voxel.dl.sourceforge.net/sourceforge/openmcdf/$(UPSTREAM_SRC).zip + wget -c http://surfnet.dl.sourceforge.net/project/openmcdf/OpenMcdf%201.x/$(UPSTREAM_SRC).zip unzip $(UPSTREAM_SRC).zip mv $(UPSTREAM_SRC_DIR) $(DEBIAN_SRC_DIR) # get rid of dll and exe files: Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/help/OpenMCDF.chm and /tmp/nyEZQEVt6N/openmcdf-1.5.4/help/OpenMCDF.chm differ diff -Nru openmcdf-1.5.2/help/sample structured storage eXplorer/OpenMcdf.xml openmcdf-1.5.4/help/sample structured storage eXplorer/OpenMcdf.xml --- openmcdf-1.5.2/help/sample structured storage eXplorer/OpenMcdf.xml 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/help/sample structured storage eXplorer/OpenMcdf.xml 2012-12-09 11:34:36.000000000 +0000 @@ -0,0 +1,1384 @@ + + + + OpenMcdf + + + + + Structured Storage signature + + + + + This integer field contains the starting sector number for the mini FAT + + + + + Provides the set of values by which a binary search tree can be enumerated. + + + + + Action to implement when transaction support - sector + has to be written to the underlying stream (see specs). + + + + + Ad-hoc Heap Friendly sector collection to avoid using + large array that may create some problem to GC collection + (see http://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/ ) + + + + + Abstract base class for Structured Storage entities. + + + + + const String STORAGE_NAME = "report.xls"; + CompoundFile cf = new CompoundFile(STORAGE_NAME); + + FileStream output = new FileStream("LogEntries.txt", FileMode.Create); + TextWriter tw = new StreamWriter(output); + + // CFItem represents both storage and stream items + VisitedEntryAction va = delegate(CFItem item) + { + tw.WriteLine(item.Name); + }; + + cf.RootStorage.VisitEntries(va, true); + + tw.Close(); + + + + + + + Get entity name + + + + + Size in bytes of the item. It has a valid value + only if entity is a stream, otherwise it is setted to zero. + + + + + Return true if item is Storage + + + This check doesn't use reflection or runtime type information + and doesn't suffer related performance penalties. + + + + + Return true if item is a Stream + + + This check doesn't use reflection or runtime type information + and doesn't suffer related performance penalties. + + + + + Return true if item is the Root Storage + + + This check doesn't use reflection or runtime type information + and doesn't suffer related performance penalties. + + + + + Get/Set the Creation Date of the current item + + + + + Get/Set the Modify Date of the current item + + + + + Get/Set Object class Guid for Root and Storage entries. + + + + + Represents a collection of Node<T> instances. + + The type of data held in the Node instances referenced by this class. + + + + Searches the NodeList for a Node containing a particular value. + + The value to search for. + The Node in the NodeList, if it exists; null otherwise. + + + + Represents a binary search tree. A binary search tree is a binary tree whose nodes are arranged + such that for any given node k, all nodes in k's left subtree have a value less than k, and all + nodes in k's right subtree have a value greater than k. + + The type of data stored in the binary tree nodes. + + + + Removes the contents of the BST + + + + + Copies the contents of the BST to an appropriately-sized array of type T, using the Inorder + traversal method. + + + + + Copies the contents of the BST to an appropriately-sized array of type T, using a specified + traversal method. + + + + + Adds a new value to the BST. + + The data to insert into the BST. + Adding a value already in the BST has no effect; that is, the SkipList is not + altered, the Add() method simply exits. + + + + Returns a Boolean, indicating if a specified value is contained within the BST. + + The data to search for. + True if data is found in the BST; false otherwise. + + + + Returns a Boolean, indicating if a specified value is contained within the BST. + + The data to search for. + True if data is found in the BST; false otherwise. + + + + Attempts to remove the specified data element from the BST. + + The data to remove from the BST. + True if the element is found in the tree, and removed; false if the element is not + found in the tree. + + + + Enumerates the BST's contents using inorder traversal. + + An enumerator that provides inorder access to the BST's elements. + + + + Enumerates the BST's contents using a specified traversal method. + + The type of traversal to perform. + An enumerator that provides access to the BST's elements using a specified traversal technique. + + + + Provides enumeration through the BST using preorder traversal. + + + + + Provides enumeration through the BST using inorder traversal. + + + + + Provides enumeration through the BST using postorder traversal. + + + + + Returns the number of elements in the BST. + + + + + Binary File Format Version. Sector size is 512 byte for version 3, + 4096 for version 4 + + + + + Compound file version 3 - The default and most common version available. Sector size 512 bytes, 2GB max file size. + + + + + Compound file version 4 - Sector size is 4096 bytes. Using this version could bring some compatibility problem with existing applications. + + + + + Update mode of the compound file. + Default is ReadOnly. + + + + + ReadOnly update mode prevents overwriting + of the opened file. + Data changes are allowed but they have to be + persisted on a different file when required. + + + + + Update mode allows subsequent data changing operations + to be persisted directly on the opened file or stream + using the Commit + method when required. Warning: this option may cause existing data loss if misused. + + + + + Standard Microsoft© Compound File implementation. + It is also known as OLE/COM structured storage + and contains a hierarchy of storage and stream objects providing + efficent storage of multiple kinds of documents in a single file. + Version 3 and 4 of specifications are supported. + + + + + Number of DIFAT entries in the header + + + + + Sector ID Size (int) + + + + + Initial capacity of the flushing queue used + to optimize commit writing operations + + + + + Maximum size of the flushing buffer used + to optimize commit writing operations + + + + + Returns the size of standard sectors switching on CFS version (3 or 4) + + Standard sector size + + + + Number of FAT entries in a DIFAT Sector + + + + + Sectors ID entries in a FAT Sector + + + + + Flag for sector recycling. + + + + + Flag for unallocated sector zeroing out. + + + + + CompoundFile header + + + + + Compound underlying stream. Null when new CF has been created. + + + + + Create a blank, version 3 compound file. + Sector recycle is turned off to achieve the best reading/writing + performance in most common scenarios. + + + + + byte[] b = new byte[10000]; + for (int i = 0; i < 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(); + + + + + + + Create a new, blank, compound file. + + Use a specific Compound File Version to set 512 or 4096 bytes sectors + If true, recycle unused sectors + If true, unallocated sectors will be overwritten with zeros + + + + byte[] b = new byte[10000]; + for (int i = 0; i < 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(); + + + + + 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. + + + + + Load an existing compound file. + + Compound file to read from + + + //A xls file should have a Workbook stream + String filename = "report.xls"; + + CompoundFile cf = new CompoundFile(filename); + CFStream foundStream = cf.RootStorage.GetStream("Workbook"); + + byte[] temp = foundStream.GetData(); + + Assert.IsNotNull(temp); + + cf.Close(); + + + + File will be open in read-only mode: it has to be saved + with a different filename. A wrapping implementation has to be provided + in order to remove/substitute an existing file. Version will be + automatically recognized from the file. Sector recycle is turned off + to achieve the best reading/writing performance in most common scenarios. + + + + + Load an existing compound file. + + Compound file to read from + If true, recycle unused sectors + Select the update mode of the underlying data file + If true, overwrite with zeros unallocated sectors + + + String srcFilename = "data_YOU_CAN_CHANGE.xls"; + + CompoundFile cf = new CompoundFile(srcFilename, UpdateMode.Update, true, true); + + Random r = new Random(); + + byte[] buffer = GetBuffer(r.Next(3, 4095), 0x0A); + + cf.RootStorage.AddStream("MyStream").SetData(buffer); + + //This will persist data to the underlying media. + cf.Commit(); + cf.Close(); + + + + + + + Load an existing compound file. + + Compound file to read from + If true, recycle unused sectors + Select the update mode of the underlying data file + If true, overwrite with zeros unallocated sectors + If true, no CFCorruptedFileException + will be thrown even if corrupted file is loaded. Please note that this option is could pose a potential security threat + + + String srcFilename = "data_YOU_CAN_CHANGE.xls"; + + CompoundFile cf = new CompoundFile(srcFilename, UpdateMode.Update, true, true, true); + + + Random r = new Random(); + + byte[] buffer = GetBuffer(r.Next(3, 4095), 0x0A); + + cf.RootStorage.AddStream("MyStream").SetData(buffer); + + //This will persist data to the underlying media. + cf.Commit(); + cf.Close(); + + + + + + + Load an existing compound file. + + A stream containing a compound file to read + If true, recycle unused sectors + Select the update mode of the underlying data file + If true, overwrite with zeros unallocated sectors + + + + String filename = "reportREAD.xls"; + + FileStream fs = new FileStream(filename, FileMode.Open); + CompoundFile cf = new CompoundFile(fs, UpdateMode.ReadOnly, false, false); + CFStream foundStream = cf.RootStorage.GetStream("Workbook"); + + byte[] temp = foundStream.GetData(); + + Assert.IsNotNull(temp); + + cf.Close(); + + + + Raised when trying to open a non-seekable stream + Raised stream is null + + + + Load an existing compound file. + + A stream containing a compound file to read + If true, recycle unused sectors + Select the update mode of the underlying data file + If true, overwrite with zeros unallocated sectors + If true, openMcdf will try to ignore invalid references or format in order to load a possibly corrupted file anyway + The 'noValidationEcxception' parameter could possibly lead to security issues so it's recommanded to use it only on trusted sources + + + + String filename = "reportREAD.xls"; + + FileStream fs = new FileStream(filename, FileMode.Open); + CompoundFile cf = new CompoundFile(fs, UpdateMode.ReadOnly, false, false, false, true); + CFStream foundStream = cf.RootStorage.GetStream("Workbook"); + + byte[] temp = foundStream.GetData(); //if 'reportRead.xls' is corrupted, openMcdf will try to lad it anyway [noValidationException set true] + + Assert.IsNotNull(temp); + + cf.Close(); + + + + Raised when trying to open a non-seekable stream + Raised stream is null + + + + Load an existing compound file from a stream. + + Streamed compound file + + + + String filename = "reportREAD.xls"; + + FileStream fs = new FileStream(filename, FileMode.Open); + CompoundFile cf = new CompoundFile(fs); + CFStream foundStream = cf.RootStorage.GetStream("Workbook"); + + byte[] temp = foundStream.GetData(); + + Assert.IsNotNull(temp); + + cf.Close(); + + + + Raised when trying to open a non-seekable stream + Raised stream is null + + + + Commit data changes since the previously commit operation + to the underlying supporting stream or file on the disk. + + + This method can be used + only if the supporting stream has been opened in + Update mode. + + + + + Commit data changes since the previously commit operation + to the underlying supporting stream or file on the disk. + + If true, release loaded sectors to limit memory usage but reduces following read operations performance + + This method can be used only if + the supporting stream has been opened in + Update mode. + + + + + Load compound file from an existing stream. + + Stream to load compound file from + + + + Allocate space, setup sectors id and refresh header + for the new or updated mini sector chain. + + The new MINI sector chain + + + + Allocate space, setup sectors id and refresh header + for the new or updated sector chain. + + The new or updated generic sector chain + + + + Check for transaction lock sector addition and mark it in the FAT. + + + + + Allocate space, setup sectors id and refresh header + for the new or updated FAT sector chain. + + The new or updated generic sector chain + + + + Setup the DIFAT sector chain + + A FAT sector chain + + + + Get the DIFAT Sector chain + + A list of DIFAT sectors + + + + Get the FAT sector chain + + List of FAT sectors + + + + Get a standard sector chain + + First SecID of the required chain + A list of sectors + + + + Get a mini sector chain + + First SecID of the required chain + A list of mini sectors (64 bytes) + + + + Get a sector chain from a compound file given the first sector ID + and the required sector type. + + First chain sector's id + Type of Sectors in the required chain (mini sectors, normal sectors or FAT) + A list of Sectors as the result of their concatenation + + + + Reset a directory entry setting it to StgInvalid in the Directory. + + Sid of the directory to invalidate + + + + Load directory entries from compound file. Header and FAT MUST be already loaded. + + + + + Commit directory entries change on the Current Source stream + + + + + Saves the in-memory image of Compound File to a file. + + File name to write the compound file to + Raised if destination file is not seekable + + + + Saves the in-memory image of Compound File to a stream. + + + Destination Stream must be seekable. + + The stream to save compound File to + Raised if destination stream is not seekable + Raised if Compound File Storage has been already disposed + + + MemoryStream ms = new MemoryStream(size); + + CompoundFile cf = new CompoundFile(); + CFStorage st = cf.RootStorage.AddStorage("MyStorage"); + CFStream sm = st.AddStream("MyStream"); + + byte[] b = new byte[]{0x00,0x01,0x02,0x03}; + + sm.SetData(b); + cf.Save(ms); + cf.Close(); + + + + + + Scan FAT o miniFAT for free sectors to reuse. + + Type of sector to look for + A stack of available sectors or minisectors already allocated + + + + + Check file size limit ( 2GB for version 3 ) + + + + + Close the Compound File object CompoundFile and + free all associated resources (e.g. open file handle and allocated memory). + + When the Close method is called, + all the associated stream and storage objects are invalidated: + any operation invoked on them will produce a CFDisposedException. + + + + + const String FILENAME = "CompoundFile.cfs"; + CompoundFile cf = new CompoundFile(FILENAME); + + CFStorage st = cf.RootStorage.GetStorage("MyStorage"); + cf.Close(); + + try + { + byte[] temp = st.GetStream("MyStream").GetData(); + + // The following line will fail because back-end object has been closed + Assert.Fail("Stream without media"); + } + catch (Exception ex) + { + Assert.IsTrue(ex is CFDisposedException); + } + + + + + + When called from user code, release all resources, otherwise, in the case runtime called it, + only unmanagd resources are released. + + If true, method has been called from User code, if false it's been called from .net runtime + + + + Get a list of all entries with a given name contained in the document. + + Name of entries to retrive + A list of name-matching entries + This function is aimed to speed up entity lookup in + flat-structure files (only one or little more known entries) + without the performance penalty related to entities hierarchy constraints. + There is no implied hierarchy in the returned list. + + + + + Compress free space by removing unallocated sectors from compound file + effectively reducing stream or file size. + + + Current implementation supports compression only for ver. 3 compound files. + + + + + //This code has been extracted from unit test + + String FILENAME = "MultipleStorage3.cfs"; + + FileInfo srcFile = new FileInfo(FILENAME); + + File.Copy(FILENAME, "MultipleStorage_Deleted_Compress.cfs", true); + + CompoundFile cf = new CompoundFile("MultipleStorage_Deleted_Compress.cfs", UpdateMode.Update, true, true); + + CFStorage st = cf.RootStorage.GetStorage("MyStorage"); + st = st.GetStorage("AnotherStorage"); + + Assert.IsNotNull(st); + st.Delete("Another2Stream"); //17Kb + cf.Commit(); + cf.Close(); + + CompoundFile.ShrinkCompoundFile("MultipleStorage_Deleted_Compress.cfs"); + + FileInfo dstFile = new FileInfo("MultipleStorage_Deleted_Compress.cfs"); + + Assert.IsTrue(srcFile.Length > dstFile.Length); + + + + + + + Remove unallocated sectors from compound file in order to reduce its size. + + + Current implementation supports compression only for ver. 3 compound files. + + + + + //This code has been extracted from unit test + + String FILENAME = "MultipleStorage3.cfs"; + + FileInfo srcFile = new FileInfo(FILENAME); + + File.Copy(FILENAME, "MultipleStorage_Deleted_Compress.cfs", true); + + CompoundFile cf = new CompoundFile("MultipleStorage_Deleted_Compress.cfs", UpdateMode.Update, true, true); + + CFStorage st = cf.RootStorage.GetStorage("MyStorage"); + st = st.GetStorage("AnotherStorage"); + + Assert.IsNotNull(st); + st.Delete("Another2Stream"); //17Kb + cf.Commit(); + cf.Close(); + + CompoundFile.ShrinkCompoundFile("MultipleStorage_Deleted_Compress.cfs"); + + FileInfo dstFile = new FileInfo("MultipleStorage_Deleted_Compress.cfs"); + + Assert.IsTrue(srcFile.Length > dstFile.Length); + + + + + + + Recursively clones valid structures, avoiding to copy free sectors. + + Current source storage to clone + Current cloned destination storage + + + + Return true if this compound file has been + loaded from an existing file or stream + + + + + The entry point object that represents the + root of the structures tree to get or set storage or + stream data. + + + + + //Create a compound file + string FILENAME = "MyFileName.cfs"; + 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(); + + + + + + OLE structured storage stream Object + It is contained inside a Storage object in a file-directory + relationship and indexed by its name. + + + + + Set the data associated with the stream object. + + + + byte[] b = new byte[]{0x0,0x1,0x2,0x3}; + CompoundFile cf = new CompoundFile(); + CFStream myStream = cf.RootStorage.AddStream("MyStream"); + myStream.SetData(b); + + + Data bytes to write to this stream + + + + Append the provided data to stream data. + + + + byte[] b = new byte[]{0x0,0x1,0x2,0x3}; + byte[] b2 = new byte[]{0x4,0x5,0x6,0x7}; + CompoundFile cf = new CompoundFile(); + CFStream myStream = cf.RootStorage.AddStream("MyStream"); + myStream.SetData(b); // here we could also have invoked .AppendData + myStream.AppendData(b2); + cf.Save("MyLargeStreamsFile.cfs); + cf.Close(); + + + Data bytes to append to this stream + + This method allows user to create stream with more than 2GB of data, + appending data to the end of existing ones. + Large streams (>2GB) are only supported by CFS version 4. + Append data can also be invoked on streams with no data in order + to simplify its use inside loops. + + + + + Get the data associated with the stream object. + + + + CompoundFile cf2 = new CompoundFile("AFileName.cfs"); + CFStream st = cf2.RootStorage.GetStream("MyStream"); + byte[] buffer = st.GetData(); + + + Array of byte containing stream data + + Raised when the owner compound file has been closed. + + + + + Get bytes associated with the stream object, starting from + a provided . When method returns, count will contain the + effective count of bytes read. + + + + CompoundFile cf = new CompoundFile("AFileName.cfs"); + CFStream st = cf.RootStorage.GetStream("MyStream"); + int count = 8; + // The stream is supposed to have a length greater than offset + count + byte[] data = st.GetData(20, ref count); + cf.Close(); + + + Array of byte containing stream data + + Raised when the owner compound file has been closed. + + + + + Copy data from an existing stream. + + A stream to read from + + Input stream is NOT closed after method invocation. + + + + + Action to apply to visited items in the OLE structured storage + + Currently visited item + + + + //We assume that xls file should be a valid OLE compound file + const String STORAGE_NAME = "report.xls"; + CompoundFile cf = new CompoundFile(STORAGE_NAME); + + FileStream output = new FileStream("LogEntries.txt", FileMode.Create); + TextWriter tw = new StreamWriter(output); + + VisitedEntryAction va = delegate(CFItem item) + { + tw.WriteLine(item.Name); + }; + + cf.RootStorage.VisitEntries(va, true); + + tw.Close(); + + + + + + + Storage entity that acts like a logic container for streams + or substorages in a compound file. + + + + + Create a new CFStorage + + The Storage Owner - CompoundFile + + + + Create a CFStorage using an existing directory (previously loaded). + + The Storage Owner - CompoundFile + An existing Directory Entry + + + + Create a new child stream inside the current storage + + The new stream name + The new stream reference + Raised when adding an item with the same name of an existing one + Raised when adding a stream to a closed compound file + Raised when adding a stream with null or empty name + + + + String filename = "A_NEW_COMPOUND_FILE_YOU_CAN_WRITE_TO.cfs"; + + CompoundFile cf = new CompoundFile(); + + CFStorage st = cf.RootStorage.AddStorage("MyStorage"); + CFStream sm = st.AddStream("MyStream"); + byte[] b = Helpers.GetBuffer(220, 0x0A); + sm.SetData(b); + + cf.Save(filename); + + + + + + + Get a named stream contained in the current storage if existing. + + Name of the stream to look for + A stream reference if existing + Raised if trying to delete item from a closed compound file + Raised if item to delete is not found + + + String filename = "report.xls"; + + CompoundFile cf = new CompoundFile(filename); + CFStream foundStream = cf.RootStorage.GetStream("Workbook"); + + byte[] temp = foundStream.GetData(); + + Assert.IsNotNull(temp); + + cf.Close(); + + + + + + Get a named storage contained in the current one if existing. + + Name of the storage to look for + A storage reference if existing. + Raised if trying to delete item from a closed compound file + Raised if item to delete is not found + + + + String FILENAME = "MultipleStorage2.cfs"; + CompoundFile cf = new CompoundFile(FILENAME, UpdateMode.ReadOnly, false, false); + + CFStorage st = cf.RootStorage.GetStorage("MyStorage"); + + Assert.IsNotNull(st); + cf.Close(); + + + + + + Create new child storage directory inside the current storage. + + The new storage name + Reference to the new storage + Raised when adding an item with the same name of an existing one + Raised when adding a storage to a closed compound file + Raised when adding a storage with null or empty name + + + + String filename = "A_NEW_COMPOUND_FILE_YOU_CAN_WRITE_TO.cfs"; + + CompoundFile cf = new CompoundFile(); + + CFStorage st = cf.RootStorage.AddStorage("MyStorage"); + CFStream sm = st.AddStream("MyStream"); + byte[] b = Helpers.GetBuffer(220, 0x0A); + sm.SetData(b); + + cf.Save(filename); + + + + + + + Visit all entities contained in the storage applying a user provided action + + Raised when visiting items of a closed compound file + User action to apply to visited entities + Visiting recursion level. True means substorages are visited recursively, false indicates that only the direct children of this storage are visited + + + const String STORAGE_NAME = "report.xls"; + CompoundFile cf = new CompoundFile(STORAGE_NAME); + + FileStream output = new FileStream("LogEntries.txt", FileMode.Create); + TextWriter tw = new StreamWriter(output); + + VisitedEntryAction va = delegate(CFItem item) + { + tw.WriteLine(item.Name); + }; + + cf.RootStorage.VisitEntries(va, true); + + tw.Close(); + + + + + + Remove an entry from the current storage and compound file. + + The name of the entry in the current storage to delete + + + cf = new CompoundFile("A_FILE_YOU_CAN_CHANGE.cfs", UpdateMode.Update, true, false); + cf.RootStorage.Delete("AStream"); // AStream item is assumed to exist. + cf.Commit(true); + cf.Close(); + + + Raised if trying to delete item from a closed compound file + Raised if item to delete is not found + Raised if trying to delete root storage + + + + FNV hash, short for Fowler/Noll/Vo + + + (not warranted) unique hash for byte array + + + + The BinaryTreeNode class represents a node in a binary tree, or a binary search tree. + It has precisely two neighbors, which can be accessed via the Left and Right properties. + + The type of data stored in the binary tree node. + + + + The Node<T> class represents the base concept of a Node for a tree or graph. It contains + a data item of type T, and a list of neighbors. + + The type of data contained in the Node. + None of the classes in the SkmDataStructures2 namespace use the Node class directly; + they all derive from this class, adding necessary functionality specific to each data structure. + + + + When called from user code, release all resources, otherwise, in the case runtime called it, + only unmanagd resources are released. + + If true, method has been called from User code, if false it's been called from .net runtime + + + + A red-black tree must satisfy these properties: + + 1. The root is black. + 2. All leaves are black. + 3. Red nodes can only have black children. + 4. All paths from a node to its leaves contain the same number of black nodes. + + + + + Add + args: ByVal key As IComparable, ByVal data As Object + key is object that implements IComparable interface + performance tip: change to use use int type (such as the hashcode) + + + + + RestoreAfterInsert + Additions to red-black trees usually destroy the red-black + properties. Examine the tree and restore. Rotations are normally + required to restore it + + + + + RotateLeft + Rebalance the tree by rotating the nodes to the left + + + + + RotateRight + Rebalance the tree by rotating the nodes to the right + + + + + + + + + + + + + + + + + RestoreAfterDelete + Deletions from red-black trees may destroy the red-black + properties. Examine the tree and restore. Rotations are normally + required to restore it + + + + + + + + + + + + Used as internal template object for binary tree searches. + + + + + The RedBlackNode class encapsulates a node in the tree + + + + + Key + + + + + Data + + + + + Color + + + + + Left + + + + + Right + + + + + OpenMCDF base exception. + + + + + Raised when a data setter/getter method is invoked + on a stream or storage object after the disposal of the owner + compound file object. + + + + + Raised when opening a file with invalid header + or not supported COM/OLE Structured storage version. + + + + + Raised when a named stream or a storage object + are not found in a parent storage. + + + + + Raised when a method call is invalid for the current object state + + + + + Raised when trying to add a duplicated CFItem + + + Items are compared by name as indicated by specs. + Two items with the same name CANNOT be added within + the same storage or sub-storage. + + + + + Raised when trying to load a Compound File with invalid, corrupted or mismatched fields (4.1 - specifications) + + + This exception is NOT raised when Compound file has been opened with NO_VALIDATION_EXCEPTION option. + + + + + Represents a binary tree. This class provides access to the Root of the tree. The developer + must manually create the binary tree by adding descendents to the root. + + The type of data stored in the binary tree's nodes. + + + + Clears out the contents of the binary tree. + + + + + Stream decorator for a Sector or miniSector chain + + + + + The RedBlackEnumerator class returns the keys or data objects of the treap in + sorted order. + + + + + Determine order, walk the tree and push the nodes onto the stack + + + + + HasMoreElements + + + + + NextElement + + + + + MoveNext + For .NET compatibility + + + + + Key + + + + + Data + + + + + The RedBlackException class distinguishes read black tree exceptions from .NET + exceptions. + + + + diff -Nru openmcdf-1.5.2/help/sample structured storage eXplorer/Readme.txt openmcdf-1.5.4/help/sample structured storage eXplorer/Readme.txt --- openmcdf-1.5.2/help/sample structured storage eXplorer/Readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/help/sample structured storage eXplorer/Readme.txt 2011-04-09 11:49:34.000000000 +0000 @@ -0,0 +1,4 @@ +Sample Structured Storage explorer source code is located in main src directory of the distribution as TESTOpenMCDF subdirectory. + +-- +This application has to be considered ONLY a sample and NOT a production tool. \ No newline at end of file diff -Nru openmcdf-1.5.2/help/sample structured storage eXplorer/StucturedStorageExplorer.exe.config openmcdf-1.5.4/help/sample structured storage eXplorer/StucturedStorageExplorer.exe.config --- openmcdf-1.5.2/help/sample structured storage eXplorer/StucturedStorageExplorer.exe.config 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/help/sample structured storage eXplorer/StucturedStorageExplorer.exe.config 2011-04-03 22:09:34.000000000 +0000 @@ -0,0 +1,15 @@ + + + + +
+ + + + + + True + + + + diff -Nru openmcdf-1.5.2/sample structured storage eXplorer/Readme.txt openmcdf-1.5.4/sample structured storage eXplorer/Readme.txt --- openmcdf-1.5.2/sample structured storage eXplorer/Readme.txt 2011-04-09 12:49:34.000000000 +0000 +++ openmcdf-1.5.4/sample structured storage eXplorer/Readme.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -Sample Structured Storage explorer source code is located in main src directory of the distribution as TESTOpenMCDF subdirectory. - --- -This application has to be considered ONLY a sample and NOT a production tool. \ No newline at end of file diff -Nru openmcdf-1.5.2/src/Html Help/OpenMcdfHelp.shfbproj openmcdf-1.5.4/src/Html Help/OpenMcdfHelp.shfbproj --- openmcdf-1.5.2/src/Html Help/OpenMcdfHelp.shfbproj 2011-04-09 12:55:10.000000000 +0000 +++ openmcdf-1.5.4/src/Html Help/OpenMcdfHelp.shfbproj 2012-10-24 21:24:56.000000000 +0000 @@ -16,7 +16,7 @@ .\Help\ OpenMCDF - Copyright 2010 - 2011 &#169%3b Federico Blaseotto + Copyright 2010 - 2012 &#169%3b Federico Blaseotto Open MCDF Open MCDF Open MCDF @@ -45,13 +45,14 @@ InheritedMembers, InheritedFrameworkMembers - - - - - - - 1.5.1.0 + + + + + + + + 1.5.3.0 Hierarchical + \ No newline at end of file diff -Nru openmcdf-1.5.2/src/OpenMcdfPerfTest/Program.cs openmcdf-1.5.4/src/OpenMcdfPerfTest/Program.cs --- openmcdf-1.5.2/src/OpenMcdfPerfTest/Program.cs 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/src/OpenMcdfPerfTest/Program.cs 2012-10-24 21:22:36.000000000 +0000 @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMcdf; +using System.IO; + +namespace OpenMcdfPerfTest +{ + class Program + { + static int MAX_STREAM_COUNT = 1000; + static String fileName = "PerfLoad.cfs"; + + static void Main(string[] args) + { + File.Delete(fileName); + if (!File.Exists(fileName)) + { + CreateFile(fileName); + } + + CompoundFile cf = new CompoundFile(fileName); + DateTime dt = DateTime.Now; + CFStream s = cf.RootStorage.GetStream("Test1"); + TimeSpan ts = DateTime.Now.Subtract(dt); + Console.WriteLine(ts.TotalMilliseconds.ToString()); + Console.Read(); + } + + private static void CreateFile(String fn) + { + CompoundFile cf = new CompoundFile(); + for (int i = 0; i < MAX_STREAM_COUNT; i++) + { + cf.RootStorage.AddStream("Test" + i.ToString()).SetData(Helpers.GetBuffer(300)); + } + cf.Save(fileName); + cf.Close(); + } + } +} diff -Nru openmcdf-1.5.2/src/OpenMcdfPerfTest/Properties/AssemblyInfo.cs openmcdf-1.5.4/src/OpenMcdfPerfTest/Properties/AssemblyInfo.cs --- openmcdf-1.5.2/src/OpenMcdfPerfTest/Properties/AssemblyInfo.cs 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/src/OpenMcdfPerfTest/Properties/AssemblyInfo.cs 2012-10-24 21:22:38.000000000 +0000 @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenMcdfPerfTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("-")] +[assembly: AssemblyProduct("OpenMcdfPerfTest")] +[assembly: AssemblyCopyright("Copyright © - 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c3a84d86-d1be-4fdc-8294-169e1f6747d8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/MainForm.Designer.cs openmcdf-1.5.4/src/TESTOpenMCDF/MainForm.Designer.cs --- openmcdf-1.5.2/src/TESTOpenMCDF/MainForm.Designer.cs 2011-04-09 12:33:20.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/MainForm.Designer.cs 2012-10-24 21:24:34.000000000 +0000 @@ -29,9 +29,7 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - this.btnOpenFile = new System.Windows.Forms.Button(); this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); - this.tbFileName = new System.Windows.Forms.TextBox(); this.treeView1 = new System.Windows.Forms.TreeView(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.importDataStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); @@ -42,54 +40,46 @@ this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.openFileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.newStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.closeStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.updateCurrentFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.tmCommitEnabled = new System.Windows.Forms.ToolStripMenuItem(); + this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.openDataFileDialog = new System.Windows.Forms.OpenFileDialog(); - this.newStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.fileNameLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.propertyGrid1 = new System.Windows.Forms.PropertyGrid(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.hexEditor = new Be.Windows.Forms.HexBox(); this.contextMenuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.Panel2.SuspendLayout(); + this.splitContainer2.SuspendLayout(); this.SuspendLayout(); // - // btnOpenFile - // - this.btnOpenFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnOpenFile.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.btnOpenFile.Location = new System.Drawing.Point(495, 38); - this.btnOpenFile.Name = "btnOpenFile"; - this.btnOpenFile.Size = new System.Drawing.Size(75, 23); - this.btnOpenFile.TabIndex = 0; - this.btnOpenFile.Text = "Open file..."; - this.btnOpenFile.UseVisualStyleBackColor = true; - this.btnOpenFile.Click += new System.EventHandler(this.btnOpenFile_Click); - // // openFileDialog1 // this.openFileDialog1.Filter = "Office files (*.xls *.doc *.ppt)|*.xls;*.doc;*.ppt|Thumbs db files (Thumbs.db)|*." + "db|MSI Setup files (*.msi)|*.msi|All files (*.*)|*.*"; this.openFileDialog1.Title = "Open OLE Structured Storae file"; // - // tbFileName - // - this.tbFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tbFileName.Enabled = false; - this.tbFileName.Location = new System.Drawing.Point(12, 40); - this.tbFileName.Name = "tbFileName"; - this.tbFileName.Size = new System.Drawing.Size(477, 20); - this.tbFileName.TabIndex = 2; - // // treeView1 // - this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.treeView1.ContextMenuStrip = this.contextMenuStrip1; - this.treeView1.Location = new System.Drawing.Point(12, 67); + this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.treeView1.HideSelection = false; + this.treeView1.Location = new System.Drawing.Point(0, 0); this.treeView1.Name = "treeView1"; - this.treeView1.Size = new System.Drawing.Size(558, 274); + this.treeView1.Size = new System.Drawing.Size(241, 240); this.treeView1.TabIndex = 4; + this.treeView1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseUp); // // contextMenuStrip1 // @@ -141,7 +131,7 @@ // saveFileDialog1 // this.saveFileDialog1.DefaultExt = "*.bin"; - this.saveFileDialog1.Filter = "Exported data files (*.bin) | *.bin|All files (*.*)|*.*"; + this.saveFileDialog1.Filter = "Exported data files (*.bin)|*.bin|All files (*.*)|*.*"; // // menuStrip1 // @@ -149,66 +139,150 @@ this.fileToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(582, 24); + this.menuStrip1.Size = new System.Drawing.Size(729, 24); this.menuStrip1.TabIndex = 5; this.menuStrip1.Text = "menuStrip1"; // // fileToolStripMenuItem // this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openFileMenuItem, this.newStripMenuItem1, - this.tmCommitEnabled, + this.closeStripMenuItem1, + this.toolStripSeparator2, this.updateCurrentFileToolStripMenuItem, - this.toolStripSeparator1, this.saveAsToolStripMenuItem}); this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); this.fileToolStripMenuItem.Text = "File"; // + // openFileMenuItem + // + this.openFileMenuItem.Image = global::StructuredStorageExplorer.Properties.Resources.folder; + this.openFileMenuItem.Name = "openFileMenuItem"; + this.openFileMenuItem.Size = new System.Drawing.Size(179, 22); + this.openFileMenuItem.Text = "Open..."; + this.openFileMenuItem.Click += new System.EventHandler(this.openFileMenuItem_Click); + // + // newStripMenuItem1 + // + this.newStripMenuItem1.Image = global::StructuredStorageExplorer.Properties.Resources.page_white; + this.newStripMenuItem1.Name = "newStripMenuItem1"; + this.newStripMenuItem1.Size = new System.Drawing.Size(179, 22); + this.newStripMenuItem1.Text = "New Compound File"; + this.newStripMenuItem1.Click += new System.EventHandler(this.newStripMenuItem1_Click); + // + // closeStripMenuItem1 + // + this.closeStripMenuItem1.Name = "closeStripMenuItem1"; + this.closeStripMenuItem1.Size = new System.Drawing.Size(179, 22); + this.closeStripMenuItem1.Text = "Close file"; + this.closeStripMenuItem1.Click += new System.EventHandler(this.closeStripMenuItem1_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(176, 6); + // + // updateCurrentFileToolStripMenuItem + // + this.updateCurrentFileToolStripMenuItem.Image = global::StructuredStorageExplorer.Properties.Resources.disk; + this.updateCurrentFileToolStripMenuItem.Name = "updateCurrentFileToolStripMenuItem"; + this.updateCurrentFileToolStripMenuItem.Size = new System.Drawing.Size(179, 22); + this.updateCurrentFileToolStripMenuItem.Text = "Save"; + this.updateCurrentFileToolStripMenuItem.Click += new System.EventHandler(this.updateCurrentFileToolStripMenuItem_Click); + // // saveAsToolStripMenuItem // this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(190, 22); + this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(179, 22); this.saveAsToolStripMenuItem.Text = "Save As..."; this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click); // - // toolStripSeparator1 + // statusStrip1 // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(187, 6); + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileNameLabel}); + this.statusStrip1.Location = new System.Drawing.Point(0, 509); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(729, 22); + this.statusStrip1.TabIndex = 6; + this.statusStrip1.Text = "statusStrip1"; // - // updateCurrentFileToolStripMenuItem + // fileNameLabel // - this.updateCurrentFileToolStripMenuItem.Enabled = false; - this.updateCurrentFileToolStripMenuItem.Name = "updateCurrentFileToolStripMenuItem"; - this.updateCurrentFileToolStripMenuItem.Size = new System.Drawing.Size(190, 22); - this.updateCurrentFileToolStripMenuItem.Text = "Update current file"; - this.updateCurrentFileToolStripMenuItem.Click += new System.EventHandler(this.updateCurrentFileToolStripMenuItem_Click); + this.fileNameLabel.Name = "fileNameLabel"; + this.fileNameLabel.Size = new System.Drawing.Size(0, 17); // - // tmCommitEnabled + // splitContainer1 // - this.tmCommitEnabled.CheckOnClick = true; - this.tmCommitEnabled.Name = "tmCommitEnabled"; - this.tmCommitEnabled.Size = new System.Drawing.Size(190, 22); - this.tmCommitEnabled.Text = "Update mode enabled"; - this.tmCommitEnabled.Click += new System.EventHandler(this.tmCommitEnabled_Click); + this.splitContainer1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; // - // newStripMenuItem1 + // splitContainer1.Panel1 // - this.newStripMenuItem1.Name = "newStripMenuItem1"; - this.newStripMenuItem1.Size = new System.Drawing.Size(190, 22); - this.newStripMenuItem1.Text = "New Compound File"; - this.newStripMenuItem1.Click += new System.EventHandler(this.newStripMenuItem1_Click); + this.splitContainer1.Panel1.Controls.Add(this.treeView1); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add(this.propertyGrid1); + this.splitContainer1.Size = new System.Drawing.Size(243, 485); + this.splitContainer1.SplitterDistance = 242; + this.splitContainer1.TabIndex = 5; + // + // propertyGrid1 + // + this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill; + this.propertyGrid1.Location = new System.Drawing.Point(0, 0); + this.propertyGrid1.Name = "propertyGrid1"; + this.propertyGrid1.Size = new System.Drawing.Size(241, 237); + this.propertyGrid1.TabIndex = 0; + this.propertyGrid1.ToolbarVisible = false; + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.Location = new System.Drawing.Point(0, 24); + this.splitContainer2.Name = "splitContainer2"; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.splitContainer1); + // + // splitContainer2.Panel2 + // + this.splitContainer2.Panel2.Controls.Add(this.hexEditor); + this.splitContainer2.Size = new System.Drawing.Size(729, 485); + this.splitContainer2.SplitterDistance = 243; + this.splitContainer2.TabIndex = 7; + // + // hexEditor + // + this.hexEditor.BackColor = System.Drawing.Color.WhiteSmoke; + this.hexEditor.Dock = System.Windows.Forms.DockStyle.Fill; + this.hexEditor.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.hexEditor.LineInfoForeColor = System.Drawing.Color.Empty; + this.hexEditor.LineInfoVisible = true; + this.hexEditor.Location = new System.Drawing.Point(0, 0); + this.hexEditor.Name = "hexEditor"; + this.hexEditor.ShadowSelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(60)))), ((int)(((byte)(188)))), ((int)(((byte)(255))))); + this.hexEditor.Size = new System.Drawing.Size(482, 485); + this.hexEditor.StringViewVisible = true; + this.hexEditor.TabIndex = 0; + this.hexEditor.UseFixedBytesPerLine = true; + this.hexEditor.VScrollBarVisible = true; // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(582, 382); + this.ClientSize = new System.Drawing.Size(729, 531); + this.Controls.Add(this.splitContainer2); + this.Controls.Add(this.statusStrip1); this.Controls.Add(this.menuStrip1); - this.Controls.Add(this.treeView1); - this.Controls.Add(this.tbFileName); - this.Controls.Add(this.btnOpenFile); this.MainMenuStrip = this.menuStrip1; this.Name = "MainForm"; this.Text = "Structured Storage eXplorer"; @@ -216,6 +290,14 @@ this.contextMenuStrip1.ResumeLayout(false); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.splitContainer1.Panel1.ResumeLayout(false); + this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.ResumeLayout(false); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel2.ResumeLayout(false); + this.splitContainer2.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -223,9 +305,7 @@ #endregion - private System.Windows.Forms.Button btnOpenFile; private System.Windows.Forms.OpenFileDialog openFileDialog1; - private System.Windows.Forms.TextBox tbFileName; private System.Windows.Forms.TreeView treeView1; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ToolStripMenuItem exportDataToolStripMenuItem; @@ -234,14 +314,21 @@ private System.Windows.Forms.MenuStrip menuStrip1; private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem tmCommitEnabled; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; private System.Windows.Forms.ToolStripMenuItem updateCurrentFileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem addStreamToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem importDataStripMenuItem1; private System.Windows.Forms.OpenFileDialog openDataFileDialog; private System.Windows.Forms.ToolStripMenuItem addStorageStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem newStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem openFileMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel fileNameLabel; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.SplitContainer splitContainer2; + private Be.Windows.Forms.HexBox hexEditor; + private System.Windows.Forms.ToolStripMenuItem closeStripMenuItem1; } } diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/MainForm.cs openmcdf-1.5.4/src/TESTOpenMCDF/MainForm.cs --- openmcdf-1.5.2/src/TESTOpenMCDF/MainForm.cs 2011-04-09 12:33:20.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/MainForm.cs 2012-10-24 21:24:38.000000000 +0000 @@ -10,15 +10,22 @@ using System.Resources; using System.Globalization; using StructuredStorageExplorer.Properties; +using Be.Windows.Forms; // Author Federico Blaseotto namespace StructuredStorageExplorer { - // Sample Structured Storage viewer to - // demonstrate use of OpenMCDF + + /// + /// Sample Structured Storage viewer to + /// demonstrate use of OpenMCDF + /// public partial class MainForm : Form { + private CompoundFile cf; + private FileStream fs; + public MainForm() { InitializeComponent(); @@ -32,47 +39,28 @@ treeView1.ImageList.Images.Add(streamImage); saveAsToolStripMenuItem.Enabled = false; - } + updateCurrentFileToolStripMenuItem.Enabled = false; - private CompoundFile cf; - private FileStream fs; + } - private void btnOpenFile_Click(object sender, EventArgs e) - { - if (openFileDialog1.ShowDialog() == DialogResult.OK) - { - try - { - OpenFile(); - } - catch - { - } - } - } private void OpenFile() { if (!String.IsNullOrEmpty(openFileDialog1.FileName)) { - if (cf != null) - cf.Close(); - - if (fs != null) - fs.Close(); + CloseCurrentFile(); treeView1.Nodes.Clear(); - tbFileName.Text = openFileDialog1.FileName; - LoadFile(openFileDialog1.FileName, tmCommitEnabled.Checked); + fileNameLabel.Text = openFileDialog1.FileName; + LoadFile(openFileDialog1.FileName, true); canUpdate = true; saveAsToolStripMenuItem.Enabled = true; + updateCurrentFileToolStripMenuItem.Enabled = true; } } - private bool canUpdate = false; - - private void CreateNewFile() + private void CloseCurrentFile() { if (cf != null) cf.Close(); @@ -80,13 +68,25 @@ if (fs != null) fs.Close(); - tbFileName.Text = String.Empty; + treeView1.Nodes.Clear(); + fileNameLabel.Text = String.Empty; + saveAsToolStripMenuItem.Enabled = false ; + updateCurrentFileToolStripMenuItem.Enabled = false; + + propertyGrid1.SelectedObject = null; + hexEditor.ByteProvider = null; + } + + private bool canUpdate = false; + + private void CreateNewFile() + { + CloseCurrentFile(); cf = new CompoundFile(); canUpdate = false; saveAsToolStripMenuItem.Enabled = true; - tmCommitEnabled.Enabled = false; updateCurrentFileToolStripMenuItem.Enabled = false; RefreshTree(); @@ -99,6 +99,7 @@ TreeNode root = null; root = treeView1.Nodes.Add("Root Entry", "Root"); root.ImageIndex = 0; + root.Tag = cf.RootStorage; //Recursive function to get all storage and streams AddNodes(root, cf.RootStorage); @@ -126,12 +127,11 @@ //Load file if (enableCommit) { - cf = new CompoundFile(fs, UpdateMode.Update, true, true); + cf = new CompoundFile(fs, UpdateMode.Update, true, true, false); } else { cf = new CompoundFile(fs); - } RefreshTree(); @@ -139,6 +139,7 @@ catch (Exception ex) { treeView1.Nodes.Clear(); + fileNameLabel.Text = String.Empty; MessageBox.Show("Internal error: " + ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } } @@ -152,13 +153,21 @@ { VisitedEntryAction va = delegate(CFItem target) { - TreeNode temp = node.Nodes.Add(target.Name, target.Name + (target is CFStorage ? "" : " (" + target.Size + " bytes )")); - - //Stream - temp.ImageIndex = 1; - temp.SelectedImageIndex = 1; + TreeNode temp = node.Nodes.Add( + target.Name, + target.Name + (target.IsStream ? " (" + target.Size + " bytes )" : "") + ); + + temp.Tag = target; + + if (target.IsStream) + { + //Stream + temp.ImageIndex = 1; + temp.SelectedImageIndex = 1; - if (target is CFStorage) + } + else { //Storage temp.ImageIndex = 0; @@ -178,27 +187,21 @@ private void exportDataToolStripMenuItem_Click(object sender, EventArgs e) { //No export if storage - if (treeView1.SelectedNode == null || treeView1.SelectedNode.ImageIndex < 1) + if (treeView1.SelectedNode == null || !((CFItem)treeView1.SelectedNode.Tag).IsStream) { MessageBox.Show("Only stream data can be exported", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } - //Remove size indicator from node path - int index = treeView1.SelectedNode.FullPath.IndexOf(" (", 0); - string path = treeView1.SelectedNode.FullPath.Remove(index); - - // Get the parts to navigate - string[] pathParts = path.Split('\\'); - + CFStream target = (CFStream)treeView1.SelectedNode.Tag; // A lot of stream and storage have only non-printable characters. // We need to sanitize filename. String sanitizedFileName = String.Empty; - foreach (char c in pathParts[pathParts.Length - 1]) + foreach (char c in target.Name) { if ( Char.GetUnicodeCategory(c) == UnicodeCategory.LetterNumber @@ -218,25 +221,12 @@ if (saveFileDialog1.ShowDialog() == DialogResult.OK) { + FileStream fs = null; - CompoundFile cf = null; - BinaryWriter bw = null; try { - cf = new CompoundFile(openFileDialog1.FileName); - CFStorage r = cf.RootStorage; - - //Navigate into the storage, following path parts - for (int i = 1; i < pathParts.Length - 1; i++) - { - r = r.GetStorage(pathParts[i]); - } - - CFStream st = r.GetStream(pathParts[pathParts.Length - 1]); - bw = new BinaryWriter(new FileStream(saveFileDialog1.FileName, FileMode.Create, FileAccess.Write, FileShare.None)); - bw.Write(st.GetData()); - - + fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite); + fs.Write(target.GetData(), 0, (int)target.Size); } catch (Exception ex) { @@ -245,179 +235,41 @@ } finally { - if (bw != null) + if (fs != null) { - bw.Flush(); - bw.Close(); + fs.Flush(); + fs.Close(); + fs = null; } - - if (cf != null) - cf.Close(); } } } - private String SelectedItemName() - { - //Remove size indicator from node path - string path = treeView1.SelectedNode.FullPath; - int index = treeView1.SelectedNode.FullPath.IndexOf(" (", 0); - - if (index != -1) - path = path.Remove(index); - - // Get the parts to navigate - string[] pathParts = path.Split('\\'); - return pathParts[pathParts.Length - 1]; - - } - - - private CFStorage SelectedStorage(bool getSelectedParent) - { - CFStorage result = null; - - //Remove size indicator from node path - string path = treeView1.SelectedNode.FullPath; - int index = treeView1.SelectedNode.FullPath.IndexOf(" (", 0); - - if (index != -1) - path = path.Remove(index); - - // Get the parts to navigate - string[] pathParts = path.Split('\\'); - - try - { - result = cf.RootStorage; - - int navTo = getSelectedParent ? pathParts.Length - 1 : pathParts.Length; - - //Navigate into the storage, following path parts - for (int i = 1; i < navTo; i++) - { - if (result.IsStorage || result.IsRoot) - result = result.GetStorage(pathParts[i]); - } - } - catch - { - MessageBox.Show("Please, select a node"); - - result = null; - } - - return result; - } - - private CFItem SelectedStream(bool getParent) - { - CFItem result = null; - CFStorage strg = null; - - //Remove size indicator from node path - string path = treeView1.SelectedNode.FullPath; - int index = treeView1.SelectedNode.FullPath.IndexOf(" (", 0); - - if (index != -1) - path = path.Remove(index); - - // Get the parts to navigate - string[] pathParts = path.Split('\\'); - - try - { - strg = cf.RootStorage; - int navTo = getParent ? pathParts.Length - 1 : pathParts.Length; - - //Navigate into the storage, following path parts - for (int i = 1; i < navTo; i++) - { - if (strg.IsStorage || strg.IsRoot) - strg = strg.GetStorage(pathParts[i]); - } - - if (getParent) - result = strg; - else - result = strg.GetStream(pathParts[pathParts.Length - 1]); - } - catch (Exception ex) - { - result = null; - } - - return result; - } - - private CFItem SelectedItem(bool getParent) - { - if (treeView1.SelectedNode == null) return null; - - if (treeView1.SelectedNode.ImageIndex == 0) - return SelectedStorage(getParent); - else - return SelectedStream(getParent); - } - private void removeToolStripMenuItem_Click(object sender, EventArgs e) { - if (!tmCommitEnabled.Checked) - { - MessageBox.Show("Removal is supported only in update mode", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); - return; - } - - CFStorage selectedItem = SelectedItem(true) as CFStorage; - - if (selectedItem != null && (selectedItem.IsStorage || selectedItem.IsRoot)) - selectedItem.Delete(SelectedItemName()); + TreeNode n = treeView1.SelectedNode; + ((CFStorage)n.Parent.Tag).Delete(n.Name); RefreshTree(); - - } private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) { + saveFileDialog1.FilterIndex = 2; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { cf.Save(saveFileDialog1.FileName); } } - private bool firstTimeChecked = true; - - private void tmCommitEnabled_Click(object sender, EventArgs e) - { - firstTimeChecked = Properties.Settings.Default.CommitEnabled; - - if (firstTimeChecked) - { - if (MessageBox.Show("Enabling update mode could lead to unwanted loss of data. Are you sure to continue ?", "Update mode is going to be enabled", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) - { - - Settings.Default.CommitEnabled = false; - Settings.Default.Save(); - - } - else - { - - tmCommitEnabled.CheckState = CheckState.Unchecked; - return; - } - } - - this.updateCurrentFileToolStripMenuItem.Enabled = tmCommitEnabled.Checked; - - OpenFile(); - } - private void updateCurrentFileToolStripMenuItem_Click(object sender, EventArgs e) { if (canUpdate) + { + if (hexEditor.ByteProvider != null && hexEditor.ByteProvider.HasChanges()) + hexEditor.ByteProvider.ApplyChanges(); cf.Commit(); + } else MessageBox.Show("Cannot update a compound document that is not based on a stream or on a file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -426,9 +278,10 @@ private void addStreamToolStripMenuItem_Click(object sender, EventArgs e) { string streamName = String.Empty; + if (Utils.InputBox("Add stream", "Insert stream name", ref streamName) == DialogResult.OK) { - CFItem cfs = SelectedItem(false); + CFItem cfs = treeView1.SelectedNode.Tag as CFItem; if (cfs != null && (cfs.IsStorage || cfs.IsRoot)) { @@ -450,9 +303,11 @@ private void addStorageStripMenuItem1_Click(object sender, EventArgs e) { string storage = String.Empty; + if (Utils.InputBox("Add storage", "Insert storage name", ref storage) == DialogResult.OK) { - CFItem cfs = SelectedItem(true); + CFItem cfs = treeView1.SelectedNode.Tag as CFItem; + if (cfs != null && (cfs.IsStorage || cfs.IsRoot)) { try @@ -475,21 +330,16 @@ if (openDataFileDialog.ShowDialog() == DialogResult.OK) { - CFStorage cfs = SelectedItem(true) as CFStorage; + CFStream s = treeView1.SelectedNode.Tag as CFStream; - if (cfs != null) + if (s != null) { - CFStream s = cfs.GetStream(SelectedItemName()); - - if (cfs != null && s != null) - { - FileStream f = new FileStream(openDataFileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read); - byte[] data = new byte[f.Length]; - f.Read(data, 0, (int)f.Length); - f.Flush(); - f.Close(); - s.SetData(data); - } + FileStream f = new FileStream(openDataFileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read); + byte[] data = new byte[f.Length]; + f.Read(data, 0, (int)f.Length); + f.Flush(); + f.Close(); + s.SetData(data); RefreshTree(); } @@ -504,33 +354,104 @@ private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) { - CFItem s = SelectedItem(false); - if (s is CFStorage) - { - addStorageStripMenuItem1.Enabled = true; - addStreamToolStripMenuItem.Enabled = true; - importDataStripMenuItem1.Enabled = false; - exportDataToolStripMenuItem.Enabled = false; - } - else - { - addStorageStripMenuItem1.Enabled = false; - addStreamToolStripMenuItem.Enabled = false; - importDataStripMenuItem1.Enabled = true; - exportDataToolStripMenuItem.Enabled = true; - } } private void newStripMenuItem1_Click(object sender, EventArgs e) { + CreateNewFile(); } + private void openFileMenuItem_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + try + { + OpenFile(); + } + catch + { + + } + } + } + + + private void treeView1_MouseUp(object sender, MouseEventArgs e) + { + // Get the node under the mouse cursor. + // We intercept both left and right mouse clicks + // and set the selected treenode according. + + TreeNode n = treeView1.GetNodeAt(e.X, e.Y); + + if (n != null) + { + if (this.hexEditor.ByteProvider != null && this.hexEditor.ByteProvider.HasChanges()) + { + if (MessageBox.Show("Do you want to save pending changes ?", "Save changes", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + { + this.hexEditor.ByteProvider.ApplyChanges(); + } + } + + treeView1.SelectedNode = n; + + + // The tag property contains the underlying CFItem. + CFItem target = (CFItem)n.Tag; + + if (target.IsStream) + { + addStorageStripMenuItem1.Enabled = false; + addStreamToolStripMenuItem.Enabled = false; + importDataStripMenuItem1.Enabled = true; + exportDataToolStripMenuItem.Enabled = true; + } + else + { + addStorageStripMenuItem1.Enabled = true; + addStreamToolStripMenuItem.Enabled = true; + importDataStripMenuItem1.Enabled = false; + exportDataToolStripMenuItem.Enabled = false; + } + propertyGrid1.SelectedObject = n.Tag; + CFStream targetStream = n.Tag as CFStream; + if (targetStream != null) + { + this.hexEditor.ByteProvider = new StreamDataProvider(targetStream); + } + else + { + this.hexEditor.ByteProvider = null; + } + } + } + + void hexEditor_ByteProviderChanged(object sender, EventArgs e) + { + + } + + private void closeStripMenuItem1_Click(object sender, EventArgs e) + { + if (this.hexEditor.ByteProvider != null && this.hexEditor.ByteProvider.HasChanges()) + { + if (MessageBox.Show("Do you want to save pending changes ?", "Save changes", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + { + this.hexEditor.ByteProvider.ApplyChanges(); + } + } + + CloseCurrentFile(); + } + } } diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/MainForm.resx openmcdf-1.5.4/src/TESTOpenMCDF/MainForm.resx --- openmcdf-1.5.2/src/TESTOpenMCDF/MainForm.resx 2011-04-03 23:09:38.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/MainForm.resx 2012-09-23 15:43:24.000000000 +0000 @@ -132,4 +132,10 @@ 529, 17 + + 676, 17 + + + 42 + \ No newline at end of file diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/Properties/AssemblyInfo.cs openmcdf-1.5.4/src/TESTOpenMCDF/Properties/AssemblyInfo.cs --- openmcdf-1.5.2/src/TESTOpenMCDF/Properties/AssemblyInfo.cs 2011-04-04 20:28:36.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/Properties/AssemblyInfo.cs 2011-07-31 08:42:28.000000000 +0000 @@ -32,4 +32,4 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.5.1.*")] +[assembly: AssemblyVersion("1.5.3.*")] diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/Properties/Resources.Designer.cs openmcdf-1.5.4/src/TESTOpenMCDF/Properties/Resources.Designer.cs --- openmcdf-1.5.2/src/TESTOpenMCDF/Properties/Resources.Designer.cs 2011-04-03 22:28:36.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/Properties/Resources.Designer.cs 2012-10-24 21:24:48.000000000 +0000 @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.3615 +// Runtime Version:2.0.50727.3634 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -60,6 +60,34 @@ } } + internal static System.Drawing.Bitmap disk { + get { + object obj = ResourceManager.GetObject("disk", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap door_out { + get { + object obj = ResourceManager.GetObject("door_out", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap folder { + get { + object obj = ResourceManager.GetObject("folder", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap page_white { + get { + object obj = ResourceManager.GetObject("page_white", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Bitmap storage { get { object obj = ResourceManager.GetObject("storage", resourceCulture); diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/Properties/Resources.resx openmcdf-1.5.4/src/TESTOpenMCDF/Properties/Resources.resx --- openmcdf-1.5.2/src/TESTOpenMCDF/Properties/Resources.resx 2011-04-03 22:28:36.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/Properties/Resources.resx 2012-10-24 21:24:44.000000000 +0000 @@ -118,6 +118,18 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\img\disk.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\img\door_out.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\img\folder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\img\page_white.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\img\storage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/StreamDataProvider.cs openmcdf-1.5.4/src/TESTOpenMCDF/StreamDataProvider.cs --- openmcdf-1.5.2/src/TESTOpenMCDF/StreamDataProvider.cs 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/StreamDataProvider.cs 2011-07-31 08:41:58.000000000 +0000 @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Be.Windows.Forms; +using OpenMcdf; + +namespace StructuredStorageExplorer +{ + public class StreamDataProvider : IByteProvider + { + /// + /// Modifying stream + /// + CFStream _modifiedStream; + + /// + /// Contains information about changes. + /// + bool _hasChanges; + + /// + /// Contains a byte collection. + /// + ByteCollection _bytes; + + + /// + /// Initializes a new instance of the DynamicByteProvider class. + /// + /// + public StreamDataProvider(CFStream modifiedStream) + { + _bytes = new ByteCollection(modifiedStream.GetData()); + _modifiedStream = modifiedStream; + } + + /// + /// Raises the Changed event. + /// + void OnChanged(EventArgs e) + { + _hasChanges = true; + + if (Changed != null) + Changed(this, e); + } + + /// + /// Raises the LengthChanged event. + /// + void OnLengthChanged(EventArgs e) + { + if (LengthChanged != null) + LengthChanged(this, e); + } + + /// + /// Gets the byte collection. + /// + public ByteCollection Bytes + { + get { return _bytes; } + } + + #region IByteProvider Members + /// + /// True, when changes are done. + /// + public bool HasChanges() + { + return _hasChanges; + } + + /// + /// Applies changes. + /// + public void ApplyChanges() + { + _hasChanges = false; + + _modifiedStream.SetData(this._bytes.ToArray()); + } + + /// + /// Occurs, when the write buffer contains new changes. + /// + public event EventHandler Changed; + + /// + /// Occurs, when InsertBytes or DeleteBytes method is called. + /// + public event EventHandler LengthChanged; + + + /// + /// Reads a byte from the byte collection. + /// + /// the index of the byte to read + /// the byte + public byte ReadByte(long index) + { return _bytes[(int)index]; } + + /// + /// Write a byte into the byte collection. + /// + /// the index of the byte to write. + /// the byte + public void WriteByte(long index, byte value) + { + _bytes[(int)index] = value; + OnChanged(EventArgs.Empty); + } + + /// + /// Deletes bytes from the byte collection. + /// + /// the start index of the bytes to delete. + /// the length of bytes to delete. + public void DeleteBytes(long index, long length) + { + int internal_index = (int)Math.Max(0, index); + int internal_length = (int)Math.Min((int)Length, length); + _bytes.RemoveRange(internal_index, internal_length); + + OnLengthChanged(EventArgs.Empty); + OnChanged(EventArgs.Empty); + } + + /// + /// Inserts byte into the byte collection. + /// + /// the start index of the bytes in the byte collection + /// the byte array to insert + public void InsertBytes(long index, byte[] bs) + { + _bytes.InsertRange((int)index, bs); + + OnLengthChanged(EventArgs.Empty); + OnChanged(EventArgs.Empty); + } + + /// + /// Gets the length of the bytes in the byte collection. + /// + public long Length + { + get + { + return _bytes.Count; + } + } + + /// + /// Returns true + /// + public bool SupportsWriteByte() + { + return true; + } + + /// + /// Returns true + /// + public bool SupportsInsertBytes() + { + return true; + } + + /// + /// Returns true + /// + public bool SupportsDeleteBytes() + { + return true; + } + #endregion + } +} diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/StructuredStorageExplorer.csproj openmcdf-1.5.4/src/TESTOpenMCDF/StructuredStorageExplorer.csproj --- openmcdf-1.5.2/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2011-04-03 23:09:42.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/StructuredStorageExplorer.csproj 2012-12-09 11:31:12.000000000 +0000 @@ -33,6 +33,7 @@ 4 + @@ -41,7 +42,8 @@ - + + Form @@ -75,8 +77,12 @@ + + + + diff -Nru openmcdf-1.5.2/src/TESTOpenMCDF/Utils.cs openmcdf-1.5.4/src/TESTOpenMCDF/Utils.cs --- openmcdf-1.5.2/src/TESTOpenMCDF/Utils.cs 1970-01-01 00:00:00.000000000 +0000 +++ openmcdf-1.5.4/src/TESTOpenMCDF/Utils.cs 2011-07-31 08:42:00.000000000 +0000 @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using OpenMcdf; + +namespace StructuredStorageExplorer +{ + class Utils + { + public static DialogResult InputBox(string title, string promptText, ref string value) + { + Form form = new Form(); + Label label = new Label(); + TextBox textBox = new TextBox(); + Button buttonOk = new Button(); + Button buttonCancel = new Button(); + + form.Text = title; + label.Text = promptText; + textBox.Text = value; + + buttonOk.Text = "OK"; + buttonCancel.Text = "Cancel"; + buttonOk.DialogResult = DialogResult.OK; + buttonCancel.DialogResult = DialogResult.Cancel; + + label.SetBounds(9, 20, 372, 13); + textBox.SetBounds(12, 36, 372, 20); + buttonOk.SetBounds(228, 72, 75, 23); + buttonCancel.SetBounds(309, 72, 75, 23); + + label.AutoSize = true; + textBox.Anchor = textBox.Anchor | AnchorStyles.Right; + buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + + form.ClientSize = new Size(396, 107); + form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel }); + form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height); + form.FormBorderStyle = FormBorderStyle.FixedDialog; + form.StartPosition = FormStartPosition.CenterScreen; + form.MinimizeBox = false; + form.MaximizeBox = false; + form.AcceptButton = buttonOk; + form.CancelButton = buttonCancel; + + DialogResult dialogResult = form.ShowDialog(); + value = textBox.Text; + return dialogResult; + } + + public static bool IsStreamTreeNode(TreeNode node) + { + return ((CFItem)node.Tag).IsStream; + } + } + + + + +} Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TESTOpenMCDF/img/disk.png and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TESTOpenMCDF/img/disk.png differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TESTOpenMCDF/img/door_out.png and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TESTOpenMCDF/img/door_out.png differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TESTOpenMCDF/img/folder.png and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TESTOpenMCDF/img/folder.png differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TESTOpenMCDF/img/page_white.png and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TESTOpenMCDF/img/page_white.png differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TestFiles/CorruptedDoc_bug3547815.doc and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TestFiles/CorruptedDoc_bug3547815.doc differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TestFiles/CorruptedDoc_bug3547815_B.doc and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TestFiles/CorruptedDoc_bug3547815_B.doc differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TestFiles/CyclicFAT.cfs and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TestFiles/CyclicFAT.cfs differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TestFiles/MultipleStorage4.cfs and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TestFiles/MultipleStorage4.cfs differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TestFiles/reportREAD.xls and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TestFiles/reportREAD.xls differ Binary files /tmp/uktgiiviLC/openmcdf-1.5.2/src/TestFiles/report_name_fix.xls and /tmp/nyEZQEVt6N/openmcdf-1.5.4/src/TestFiles/report_name_fix.xls differ