public void Test_WRITE_STREAM_WITH_DIFAT() { //const int SIZE = 15388609; //Incredible condition of 'resonance' between FAT and DIFAT sec number const int SIZE = 15345665; // 64 -> 65 NOT working (in the past ;-) ) byte[] b = Helpers.GetBuffer(SIZE, 0); CompoundFile cf = new CompoundFile(); ICFStream myStream = cf.RootStorage.AddStream("MyStream"); Assert.IsNotNull(myStream); myStream.SetData(b); cf.Save("WRITE_STREAM_WITH_DIFAT.cfs"); cf.Close(); CompoundFile cf2 = new CompoundFile("WRITE_STREAM_WITH_DIFAT.cfs"); ICFStream st = cf2.RootStorage.GetStream("MyStream"); Assert.IsNotNull(cf2); Assert.IsTrue(st.Size == SIZE); Assert.IsTrue(Helpers.CompareBuffer(b, st.GetData())); cf2.Close(); if (File.Exists("WRITE_STREAM_WITH_DIFAT.cfs")) { File.Delete("WRITE_STREAM_WITH_DIFAT.cfs"); } }
private void SingleWriteReadMatching(int size) { String filename = "INCREMENTAL_SIZE_MULTIPLE_WRITE_AND_READ_CFS.cfs"; if (File.Exists(filename)) { File.Delete(filename); } CompoundFile cf = new CompoundFile(); ICFStorage st = cf.RootStorage.AddStorage("MyStorage"); ICFStream sm = st.AddStream("MyStream"); byte[] b = Helpers.GetBuffer(size); sm.SetData(b); cf.Save(filename); cf.Close(); CompoundFile cf2 = new CompoundFile(filename); ICFStorage st2 = cf2.RootStorage.GetStorage("MyStorage"); ICFStream sm2 = st2.GetStream("MyStream"); Assert.IsNotNull(sm2); Assert.IsTrue(sm2.Size == size); Assert.IsTrue(Helpers.CompareBuffer(sm2.GetData(), b)); cf2.Close(); }
public void Test_OPEN_COMPOUND_BUG_FIX_133() { var f = new CompoundFile("testbad.ole"); ICFStream cfs = f.RootStorage.GetStream("\x01Ole10Native"); byte[] data = cfs.GetData(); Assert.IsTrue(data.Length == 18140); }
/// <summary> /// Creates this object and reads all the properties from the toplevel stream /// </summary> /// <param name="stream">The <see cref="CFStream"/></param> internal TopLevelPropertiesStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { //binaryReader.ReadBytes(8); NextRecipientId = Convert.ToInt32(binaryReader.ReadUInt32()); NextAttachmentId = Convert.ToInt32(binaryReader.ReadUInt32()); RecipientCount = Convert.ToInt32(binaryReader.ReadUInt32()); AttachmentCount = Convert.ToInt32(binaryReader.ReadUInt32()); ReadProperties(binaryReader); } }
public void Test_TRANSACTED_ADD_REMOVE_MULTIPLE_STREAM_TO_EXISTING_FILE() { String srcFilename = "report.xls"; String dstFilename = "reportOverwriteMultiple.xls"; File.Copy(srcFilename, dstFilename, true); CompoundFile cf = new CompoundFile(dstFilename, UpdateMode.ReadOnly, true, false); //CompoundFile cf = new CompoundFile(); Random r = new Random(); for (int i = 0; i < 254; i++) { //byte[] buffer = Helpers.GetBuffer(r.Next(100, 3500), (byte)i); byte[] buffer = Helpers.GetBuffer(1995, 1); //if (i > 0) //{ // if (r.Next(0, 100) > 50) // { // cf.RootStorage.Delete("MyNewStream" + (i - 1).ToString()); // } //} ICFStream addedStream = cf.RootStorage.AddStream("MyNewStream" + i.ToString()); Assert.IsNotNull(addedStream, "Stream not found"); addedStream.SetData(buffer); Assert.IsTrue(Helpers.CompareBuffer(addedStream.GetData(), buffer), "Data buffer corrupted"); // Random commit, not on single addition //if (r.Next(0, 100) > 50) // cf.UpdateFile(); } cf.Save(dstFilename + "PP"); cf.Close(); if (File.Exists("reportOverwriteMultiple.xls")) { File.Delete("reportOverwriteMultiple.xls"); } if (File.Exists("reportOverwriteMultiple.xlsPP")) { File.Delete("reportOverwriteMultiple.xlsPP"); } }
public void Test_READ_STREAM() { String filename = "report.xls"; CompoundFile cf = new CompoundFile(filename); ICFStream foundStream = cf.RootStorage.GetStream("Workbook"); byte[] temp = foundStream.GetData(); Assert.IsNotNull(temp); Assert.IsTrue(temp.Length > 0); cf.Close(); }
public void Test_OPEN_FROM_STREAM() { String filename = "reportREAD.xls"; File.Copy(filename, "reportOPENFROMSTREAM.xls"); FileStream fs = new FileStream(filename, FileMode.Open); CompoundFile cf = new CompoundFile(fs); ICFStream foundStream = cf.RootStorage.GetStream("Workbook"); byte[] temp = foundStream.GetData(); Assert.IsNotNull(temp); cf.Close(); }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage AttachDesc <see cref="CFStream" /></param> internal AttachDescStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { Version = binaryReader.ReadUInt16(); LongPathName = Strings.Read1ByteLengthPrefixedAnsiString(binaryReader); PathName = Strings.Read1ByteLengthPrefixedAnsiString(binaryReader); DisplayName = Strings.Read1ByteLengthPrefixedAnsiString(binaryReader); LongFileName = Strings.Read1ByteLengthPrefixedAnsiString(binaryReader); FileName = Strings.Read1ByteLengthPrefixedAnsiString(binaryReader); Extension = Strings.Read1ByteLengthPrefixedAnsiString(binaryReader); var fileCreationTime = binaryReader.ReadBytes(8).ToArray(); FileCreationTime = DateTime.FromFileTime(BitConverter.ToInt64(fileCreationTime, 0)); var fileLastModifiedTime = binaryReader.ReadBytes(8).ToArray(); FileLastModifiedTime = DateTime.FromFileTime(BitConverter.ToInt64(fileLastModifiedTime, 0)); } }
private void SingleWriteReadMatchingSTREAMED(int size) { MemoryStream ms = new MemoryStream(size); CompoundFile cf = new CompoundFile(); ICFStorage st = cf.RootStorage.AddStorage("MyStorage"); ICFStream sm = st.AddStream("MyStream"); byte[] b = Helpers.GetBuffer(size); sm.SetData(b); cf.Save(ms); cf.Close(); CompoundFile cf2 = new CompoundFile(ms); ICFStorage st2 = cf2.RootStorage.GetStorage("MyStorage"); ICFStream sm2 = st2.GetStream("MyStream"); Assert.IsNotNull(sm2); Assert.IsTrue(sm2.Size == size); Assert.IsTrue(Helpers.CompareBuffer(sm2.GetData(), b)); cf2.Close(); }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage CompObj <see cref="CFStream" /></param> internal ObjInfoStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { var bytes = binaryReader.ReadBytes(2); var bitArray = new BitArray(bytes); // A - reserved1 (1 bit): Undefined and MUST be ignored. // B - fDefHandler (1 bit): If this bit is 1, then the application MUST assume that this OLE object’s // class identifier (CLSID) is {00020907-0000-0000-C000-000000000046}. DefHandler = bitArray.Get(1); // C - reserved2 (1 bit): Undefined and MUST be ignored. // D - reserved3 (1 bit): Undefined and MUST be ignored. // E - fLink (1 bit): A bit that specifies whether this OLE object is a link. Link = bitArray.Get(4); // F - reserved4 (1 bit): Undefined and MUST be ignored. // G - fIcon (1 bit): A bit that specifies whether this OLE object is being represented by an icon. Icon = bitArray.Get(6); // H - fIsOle1 (1 bit): A bit that specifies whether this OLE object is only compatible with OLE 1. // If this bit is zero, then the object is compatible with OLE 2. IsOle1 = bitArray.Get(7); // I - fManual (1 bit): A bit that specifies whether the user has requested that this OLE object only // be updated in response to a user action. If fManual is zero, then the user has requested that // this OLE object update automatically. If fLink is zero, then fManual is undefined and MUST be ignored. Manual = bitArray.Get(8); // J - fRecomposeOnResize (1 bit): A bit that specifies whether this OLE object has requested to be notified // when it is resized by its container. RecomposeOnResize = bitArray.Get(9); // K - reserved5 (1 bit): MUST be zero and MUST be ignored. // L - reserved6 (1 bit): MUST be zero and MUST be ignored. // M - fOCX (1 bit): A bit that specifies whether this object is an OLE control. Ocx = bitArray.Get(12); // N - fStream (1 bit): If fOCX is zero, then this bit MUST be zero. If fOCX is 1, then fStream is a bit that // specifies whether this OLE control stores its data in a single stream instead of a storage. If fStream // is 1, then the data for the OLE control is in a stream called "\003OCXDATA" where \003 is the character // with value 0x0003, not the string literal "\003". Stream = bitArray.Get(13); // O - reserved7 (1 bit): Undefined and MUST be ignored. // P - fViewObject (1 bit): A bit that specifies whether this OLE object supports the IViewObject interface. ViewObject = bitArray.Get(15); try { Cf = (OleCf) binaryReader.ReadUInt16(); } catch (Exception) { Cf = OleCf.UnSpecified; } } }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage CompObj <see cref="CFStream" /></param> internal ObjInfoStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { var bytes = binaryReader.ReadBytes(2); var bitArray = new BitArray(bytes); // A - reserved1 (1 bit): Undefined and MUST be ignored. // B - fDefHandler (1 bit): If this bit is 1, then the application MUST assume that this OLE object’s // class identifier (CLSID) is {00020907-0000-0000-C000-000000000046}. DefHandler = bitArray.Get(1); // C - reserved2 (1 bit): Undefined and MUST be ignored. // D - reserved3 (1 bit): Undefined and MUST be ignored. // E - fLink (1 bit): A bit that specifies whether this OLE object is a link. Link = bitArray.Get(4); // F - reserved4 (1 bit): Undefined and MUST be ignored. // G - fIcon (1 bit): A bit that specifies whether this OLE object is being represented by an icon. Icon = bitArray.Get(6); // H - fIsOle1 (1 bit): A bit that specifies whether this OLE object is only compatible with OLE 1. // If this bit is zero, then the object is compatible with OLE 2. IsOle1 = bitArray.Get(7); // I - fManual (1 bit): A bit that specifies whether the user has requested that this OLE object only // be updated in response to a user action. If fManual is zero, then the user has requested that // this OLE object update automatically. If fLink is zero, then fManual is undefined and MUST be ignored. Manual = bitArray.Get(8); // J - fRecomposeOnResize (1 bit): A bit that specifies whether this OLE object has requested to be notified // when it is resized by its container. RecomposeOnResize = bitArray.Get(9); // K - reserved5 (1 bit): MUST be zero and MUST be ignored. // L - reserved6 (1 bit): MUST be zero and MUST be ignored. // M - fOCX (1 bit): A bit that specifies whether this object is an OLE control. Ocx = bitArray.Get(12); // N - fStream (1 bit): If fOCX is zero, then this bit MUST be zero. If fOCX is 1, then fStream is a bit that // specifies whether this OLE control stores its data in a single stream instead of a storage. If fStream // is 1, then the data for the OLE control is in a stream called "\003OCXDATA" where \003 is the character // with value 0x0003, not the string literal "\003". Stream = bitArray.Get(13); // O - reserved7 (1 bit): Undefined and MUST be ignored. // P - fViewObject (1 bit): A bit that specifies whether this OLE object supports the IViewObject interface. ViewObject = bitArray.Get(15); try { Cf = (OleCf)binaryReader.ReadUInt16(); } catch (Exception) { Cf = OleCf.UnSpecified; } } }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage Ole <see cref="CFStream" /></param> internal OleStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { Version = binaryReader.ReadUInt16(); // Flags (4 bytes): If this field is set to 0x00000001, the OLEStream structure MUST be for a linked object and // the CLSID field of the Compound File Directory Entry of the OLE Compound File Storage object MUST be set to // CLSID_StdOleLink ({00000300-0000-0000-C000-000000000046}). If this field is set to 0x00000000, then the OLEStream // structure MUST be for an embedded object and the CLSID field of the Compound File Directory Entry // of the OLE Compound File Storage object MUST be set to the object class GUID of the creating application. var flags = binaryReader.ReadUInt32(); switch (flags) { case 0x00000000: case 0x00001000: Format = OleFormat.File; break; case 0x00000001: case 0x00001001: Format = OleFormat.Link; break; } // LinkUpdateOption (4 bytes): This field contains an implementation-specific hint supplied by the application or by // a higher-level protocol that creates the data structure. The hint MAY be ignored on processing of this data structure LinkUpdateOptions = binaryReader.ReadUInt32(); //Reserved1 (4 bytes): This MUST be set to 0x00000000. Otherwise, the OLEStream structure is invalid binaryReader.ReadUInt32(); // ReservedMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the ReservedMonikerStream field. If this // field has a value 0x00000000, the ReservedMonikerStream field MUST NOT be present. var reservedMonikerStreamSize = (int) binaryReader.ReadUInt32(); // ReservedMonikerStream (variable): This MUST be a MONIKERSTREAM structure that can contain any arbitrary // value and MUST be ignored on processing. binaryReader.ReadBytes(reservedMonikerStreamSize); // Note The fields that follow MUST NOT be present if the OLEStream structure is for an embedded object. if (Format == OleFormat.Link) { // RelativeSourceMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the RelativeSourceMonikerStream field. // If this field has a value 0x00000000, the RelativeSourceMonikerStream field MUST NOT be present. var relativeSourceMonikerStreamSize = (int) binaryReader.ReadUInt32(); // RelativeSourceMonikerStream (variable): This MUST be a MONIKERSTREAM structure that specifies the relative // path to the linked object. if (relativeSourceMonikerStreamSize > 0) RelativeSource = new MonikerStream(binaryReader, relativeSourceMonikerStreamSize); // AbsoluteSourceMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the AbsoluteSourceMonikerStream field. // This field MUST NOT contain the value 0x00000000. var absoluteSourceMonikerStreamSize = (int) binaryReader.ReadUInt32(); // AbsoluteSourceMonikerStream (variable): This MUST be a MONIKERSTREAM structure that specifies the full path // to the linked object. if (absoluteSourceMonikerStreamSize > 0) AbsoluteSource = new MonikerStream(binaryReader, absoluteSourceMonikerStreamSize); // If the RelativeSourceMonikerStream field is present, it MUST be used by the container application instead of the // AbsoluteSourceMonikerStream. If the RelativeSourceMonikerStream field is not present, the AbsoluteSourceMonikerStream MUST be used // by the container application. // ClsidIndicator (4 bytes): This MUST be the LONG as specified in section value -1. Otherwise the OLEStream // structure is invalid. binaryReader.ReadUInt32(); // Clsid (16 bytes): This MUST be the CLSID (Packet) containing the object class GUID of the creating application. Clsid = new CLSID(binaryReader); // ReservedDisplayName (4 bytes): This MUST be a LengthPrefixedUnicodeString that can contain any arbitrary value // and MUST be ignored on processing. binaryReader.ReadUInt32(); // Reserved2 (4 bytes): This can contain any arbitrary value and MUST be ignored on processing. binaryReader.ReadUInt32(); // LocalUpdateTime (4 bytes): This MUST be a FILETIME (Packet) that contains the time when the container application // last updated the RemoteUpdateTime field. var localUpdateTime = binaryReader.ReadBytes(4).Reverse().ToArray(); LocalUpdateTime = DateTime.FromFileTime(BitConverter.ToInt32(localUpdateTime, 0)); // LocalCheckUpdateTime (4 bytes): This MUST be a FILETIME (Packet) that contains the time when the container application last // checked the update time of the linked object. var localCheckUpdateTime = binaryReader.ReadBytes(4).Reverse().ToArray(); LocalCheckUpdateTime = DateTime.FromFileTime(BitConverter.ToInt32(localCheckUpdateTime, 0)); // RemoteUpdateTime (4 bytes): This MUST be a FILETIME (Packet) that contains the time when the linked object was last updated. var remoteUpdateTime = binaryReader.ReadBytes(4).Reverse().ToArray(); RemoteUpdateTime = DateTime.FromFileTime(BitConverter.ToInt32(remoteUpdateTime, 0)); } } }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage Ole <see cref="CFStream" /></param> internal OleStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { Version = binaryReader.ReadUInt16(); // Flags (4 bytes): If this field is set to 0x00000001, the OLEStream structure MUST be for a linked object and // the CLSID field of the Compound File Directory Entry of the OLE Compound File Storage object MUST be set to // CLSID_StdOleLink ({00000300-0000-0000-C000-000000000046}). If this field is set to 0x00000000, then the OLEStream // structure MUST be for an embedded object and the CLSID field of the Compound File Directory Entry // of the OLE Compound File Storage object MUST be set to the object class GUID of the creating application. var flags = binaryReader.ReadUInt32(); switch (flags) { case 0x00000000: case 0x00001000: Format = OleFormat.File; break; case 0x00000001: case 0x00001001: Format = OleFormat.Link; break; } // LinkUpdateOption (4 bytes): This field contains an implementation-specific hint supplied by the application or by // a higher-level protocol that creates the data structure. The hint MAY be ignored on processing of this data structure LinkUpdateOptions = binaryReader.ReadUInt32(); //Reserved1 (4 bytes): This MUST be set to 0x00000000. Otherwise, the OLEStream structure is invalid binaryReader.ReadUInt32(); // ReservedMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the ReservedMonikerStream field. If this // field has a value 0x00000000, the ReservedMonikerStream field MUST NOT be present. var reservedMonikerStreamSize = (int)binaryReader.ReadUInt32(); // ReservedMonikerStream (variable): This MUST be a MONIKERSTREAM structure that can contain any arbitrary // value and MUST be ignored on processing. binaryReader.ReadBytes(reservedMonikerStreamSize); // Note The fields that follow MUST NOT be present if the OLEStream structure is for an embedded object. if (Format == OleFormat.Link) { // RelativeSourceMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the RelativeSourceMonikerStream field. // If this field has a value 0x00000000, the RelativeSourceMonikerStream field MUST NOT be present. var relativeSourceMonikerStreamSize = (int)binaryReader.ReadUInt32(); // RelativeSourceMonikerStream (variable): This MUST be a MONIKERSTREAM structure that specifies the relative // path to the linked object. if (relativeSourceMonikerStreamSize > 0) { RelativeSource = new MonikerStream(binaryReader, relativeSourceMonikerStreamSize); } // AbsoluteSourceMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the AbsoluteSourceMonikerStream field. // This field MUST NOT contain the value 0x00000000. var absoluteSourceMonikerStreamSize = (int)binaryReader.ReadUInt32(); // AbsoluteSourceMonikerStream (variable): This MUST be a MONIKERSTREAM structure that specifies the full path // to the linked object. if (absoluteSourceMonikerStreamSize > 0) { AbsoluteSource = new MonikerStream(binaryReader, absoluteSourceMonikerStreamSize); } // If the RelativeSourceMonikerStream field is present, it MUST be used by the container application instead of the // AbsoluteSourceMonikerStream. If the RelativeSourceMonikerStream field is not present, the AbsoluteSourceMonikerStream MUST be used // by the container application. // ClsidIndicator (4 bytes): This MUST be the LONG as specified in section value -1. Otherwise the OLEStream // structure is invalid. binaryReader.ReadUInt32(); // Clsid (16 bytes): This MUST be the CLSID (Packet) containing the object class GUID of the creating application. Clsid = new CLSID(binaryReader); // ReservedDisplayName (4 bytes): This MUST be a LengthPrefixedUnicodeString that can contain any arbitrary value // and MUST be ignored on processing. binaryReader.ReadUInt32(); // Reserved2 (4 bytes): This can contain any arbitrary value and MUST be ignored on processing. binaryReader.ReadUInt32(); // LocalUpdateTime (4 bytes): This MUST be a FILETIME (Packet) that contains the time when the container application // last updated the RemoteUpdateTime field. var localUpdateTime = binaryReader.ReadBytes(4).Reverse().ToArray(); LocalUpdateTime = DateTime.FromFileTime(BitConverter.ToInt32(localUpdateTime, 0)); // LocalCheckUpdateTime (4 bytes): This MUST be a FILETIME (Packet) that contains the time when the container application last // checked the update time of the linked object. var localCheckUpdateTime = binaryReader.ReadBytes(4).Reverse().ToArray(); LocalCheckUpdateTime = DateTime.FromFileTime(BitConverter.ToInt32(localCheckUpdateTime, 0)); // RemoteUpdateTime (4 bytes): This MUST be a FILETIME (Packet) that contains the time when the linked object was last updated. var remoteUpdateTime = binaryReader.ReadBytes(4).Reverse().ToArray(); RemoteUpdateTime = DateTime.FromFileTime(BitConverter.ToInt32(remoteUpdateTime, 0)); } } }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage CompObj <see cref="CFStream" /></param> internal CompObjStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { // Reserved1 (4 bytes): This can be set to any arbitrary value and MUST be ignored on processing. // Version (4 bytes): This can be set to any arbitrary value and MUST be ignored on processing. // Reserved2 (20 bytes): This can be set to any arbitrary value and MUST be ignored on processing. // Skip the first 28 bytes, this is the CompObjHeader binaryReader.ReadBytes(28); // This MUST be a LengthPrefixedAnsiString structure that contains a display name of the linked // object or embedded object. AnsiUserType = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); // MarkerOrLength (4 bytes): If this is set to 0x00000000, the FormatOrAnsiString field MUST NOT // be present. If this field is set to 0xFFFFFFFF or 0xFFFFFFFE, the FormatOrAnsiString field MUST // be 4 bytes in size and MUST contain a standard clipboard format identifier. // If this set to a value other than 0x00000000, the FormatOrAnsiString field MUST be set to a // null-terminated ANSI string containing the name of a registered clipboard format and the // MarkerOrLength field MUST be set to the number of ANSI characters in the FormatOrAnsiString field, // including the terminating null character. var markerOrLength = binaryReader.ReadUInt32(); switch (markerOrLength) { case 0x00000000: // Skip break; case 0xFFFFFFFF: case 0xFFFFFFFE: ClipboardFormat = (OleClipboardFormat) binaryReader.ReadUInt32(); break; default: binaryReader.BaseStream.Position -= 4; StringFormat = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); break; } // Reserved1 (variable): If present, this MUST be a LengthPrefixedAnsiString structure. If the Length // field of the LengthPrefixedAnsiString contains a value of 0 or a value that is greater than 0x00000028, // the remaining fields of the structure starting with the String field of the LengthPrefixedAnsiString // MUST be ignored on processing. var reserved1Length = binaryReader.ReadUInt32(); if (reserved1Length <= 0x00000028) { binaryReader.BaseStream.Position -= 4; // ReSharper disable once UnusedVariable var reserved1 = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); } // UnicodeMarker (variable): If this field is present and is NOT set to 0x71B239F4, the remaining fields // of the structure MUST be ignored on processing. var unicodeMarker = binaryReader.ReadUInt32(); if (unicodeMarker == 0x71B239F4) { markerOrLength = binaryReader.ReadUInt32(); switch (markerOrLength) { case 0x00000000: // Skip break; case 0xFFFFFFFF: case 0xFFFFFFFE: ClipboardFormat = (OleClipboardFormat) binaryReader.ReadUInt32(); break; default: binaryReader.BaseStream.Position -= 4; StringFormat = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); break; } } } }
public void Test_WRITE_MINISTREAM_READ_REWRITE_STREAM() { const int BIGGER_SIZE = 350; //const int SMALLER_SIZE = 290; const int MEGA_SIZE = 18000000; byte[] ba1 = Helpers.GetBuffer(BIGGER_SIZE, 1); byte[] ba2 = Helpers.GetBuffer(BIGGER_SIZE, 2); byte[] ba3 = Helpers.GetBuffer(BIGGER_SIZE, 3); byte[] ba4 = Helpers.GetBuffer(BIGGER_SIZE, 4); byte[] ba5 = Helpers.GetBuffer(BIGGER_SIZE, 5); //WRITE 5 (mini)streams in a compound file -- CompoundFile cfa = new CompoundFile(); ICFStream myStream = cfa.RootStorage.AddStream("MyFirstStream"); Assert.IsNotNull(myStream); myStream.SetData(ba1); Assert.IsTrue(myStream.Size == BIGGER_SIZE); ICFStream myStream2 = cfa.RootStorage.AddStream("MySecondStream"); Assert.IsNotNull(myStream2); myStream2.SetData(ba2); Assert.IsTrue(myStream2.Size == BIGGER_SIZE); ICFStream myStream3 = cfa.RootStorage.AddStream("MyThirdStream"); Assert.IsNotNull(myStream3); myStream3.SetData(ba3); Assert.IsTrue(myStream3.Size == BIGGER_SIZE); ICFStream myStream4 = cfa.RootStorage.AddStream("MyFourthStream"); Assert.IsNotNull(myStream4); myStream4.SetData(ba4); Assert.IsTrue(myStream4.Size == BIGGER_SIZE); ICFStream myStream5 = cfa.RootStorage.AddStream("MyFifthStream"); Assert.IsNotNull(myStream5); myStream5.SetData(ba5); Assert.IsTrue(myStream5.Size == BIGGER_SIZE); cfa.Save("WRITE_MINISTREAM_READ_REWRITE_STREAM.cfs"); cfa.Close(); // Now get the second stream and rewrite it smaller byte[] bb = Helpers.GetBuffer(MEGA_SIZE); CompoundFile cfb = new CompoundFile("WRITE_MINISTREAM_READ_REWRITE_STREAM.cfs"); ICFStream myStreamB = cfb.RootStorage.GetStream("MySecondStream"); Assert.IsNotNull(myStreamB); myStreamB.SetData(bb); Assert.IsTrue(myStreamB.Size == MEGA_SIZE); byte[] bufferB = myStreamB.GetData(); cfb.Save("WRITE_MINISTREAM_READ_REWRITE_STREAM_2ND.cfs"); cfb.Close(); CompoundFile cfc = new CompoundFile("WRITE_MINISTREAM_READ_REWRITE_STREAM_2ND.cfs"); ICFStream myStreamC = cfc.RootStorage.GetStream("MySecondStream"); Assert.IsTrue(myStreamC.Size == MEGA_SIZE, "DATA SIZE FAILED"); byte[] bufferC = myStreamC.GetData(); Assert.IsTrue(Helpers.CompareBuffer(bufferB, bufferC), "DATA INTEGRITY FAILED"); cfc.Close(); if (File.Exists("WRITE_MINISTREAM_READ_REWRITE_STREAM.cfs")) { File.Delete("WRITE_MINISTREAM_READ_REWRITE_STREAM.cfs"); } if (File.Exists("WRITE_MINISTREAM_READ_REWRITE_STREAM_2ND.cfs")) { File.Delete("WRITE_MINISTREAM_READ_REWRITE_STREAM_2ND.cfs"); } }
/// <summary> /// Creates this object and sets all its properties /// </summary> /// <param name="stream">The Compound File Storage CompObj <see cref="CFStream" /></param> internal CompObjStream(ICFStream stream) { using (var memoryStream = new MemoryStream(stream.GetData())) using (var binaryReader = new BinaryReader(memoryStream)) { // Reserved1 (4 bytes): This can be set to any arbitrary value and MUST be ignored on processing. // Version (4 bytes): This can be set to any arbitrary value and MUST be ignored on processing. // Reserved2 (20 bytes): This can be set to any arbitrary value and MUST be ignored on processing. // Skip the first 28 bytes, this is the CompObjHeader binaryReader.ReadBytes(28); // This MUST be a LengthPrefixedAnsiString structure that contains a display name of the linked // object or embedded object. AnsiUserType = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); // MarkerOrLength (4 bytes): If this is set to 0x00000000, the FormatOrAnsiString field MUST NOT // be present. If this field is set to 0xFFFFFFFF or 0xFFFFFFFE, the FormatOrAnsiString field MUST // be 4 bytes in size and MUST contain a standard clipboard format identifier. // If this set to a value other than 0x00000000, the FormatOrAnsiString field MUST be set to a // null-terminated ANSI string containing the name of a registered clipboard format and the // MarkerOrLength field MUST be set to the number of ANSI characters in the FormatOrAnsiString field, // including the terminating null character. var markerOrLength = binaryReader.ReadUInt32(); switch (markerOrLength) { case 0x00000000: // Skip break; case 0xFFFFFFFF: case 0xFFFFFFFE: ClipboardFormat = (OleClipboardFormat)binaryReader.ReadUInt32(); break; default: binaryReader.BaseStream.Position -= 4; StringFormat = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); break; } // Reserved1 (variable): If present, this MUST be a LengthPrefixedAnsiString structure. If the Length // field of the LengthPrefixedAnsiString contains a value of 0 or a value that is greater than 0x00000028, // the remaining fields of the structure starting with the String field of the LengthPrefixedAnsiString // MUST be ignored on processing. var reserved1Length = binaryReader.ReadUInt32(); if (reserved1Length <= 0x00000028) { binaryReader.BaseStream.Position -= 4; // ReSharper disable once UnusedVariable var reserved1 = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); } // UnicodeMarker (variable): If this field is present and is NOT set to 0x71B239F4, the remaining fields // of the structure MUST be ignored on processing. var unicodeMarker = binaryReader.ReadUInt32(); if (unicodeMarker == 0x71B239F4) { markerOrLength = binaryReader.ReadUInt32(); switch (markerOrLength) { case 0x00000000: // Skip break; case 0xFFFFFFFF: case 0xFFFFFFFE: ClipboardFormat = (OleClipboardFormat)binaryReader.ReadUInt32(); break; default: binaryReader.BaseStream.Position -= 4; StringFormat = Strings.Read4ByteLengthPrefixedAnsiString(binaryReader); break; } } } }
public void Test_FUNCTIONAL_BEHAVIOUR() { const int N_FACTOR = 1; byte[] bA = Helpers.GetBuffer(20 * 1024 * N_FACTOR, 0x0A); byte[] bB = Helpers.GetBuffer(5 * 1024, 0x0B); byte[] bC = Helpers.GetBuffer(5 * 1024, 0x0C); byte[] bD = Helpers.GetBuffer(5 * 1024, 0x0D); byte[] bE = Helpers.GetBuffer(8 * 1024 * N_FACTOR + 1, 0x1A); byte[] bF = Helpers.GetBuffer(16 * 1024 * N_FACTOR, 0x1B); byte[] bG = Helpers.GetBuffer(14 * 1024 * N_FACTOR, 0x1C); byte[] bH = Helpers.GetBuffer(12 * 1024 * N_FACTOR, 0x1D); byte[] bE2 = Helpers.GetBuffer(8 * 1024 * N_FACTOR, 0x2A); byte[] bMini = Helpers.GetBuffer(1027, 0xEE); Stopwatch sw = new Stopwatch(); sw.Start(); //############ // Phase 1 var cf = new CompoundFile(CFSVersion.Ver_3, true, false); cf.RootStorage.AddStream("A").SetData(bA); cf.Save("OneStream.cfs"); cf.Close(); // Test Phase 1 var cfTest = new CompoundFile("OneStream.cfs"); ICFStream testSt = cfTest.RootStorage.GetStream("A"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bA.Length); Assert.IsTrue(Helpers.CompareBuffer(bA, testSt.GetData())); cfTest.Close(); //########### //Phase 2 cf = new CompoundFile("OneStream.cfs", UpdateMode.ReadOnly, true, false); cf.RootStorage.AddStream("B").SetData(bB); cf.RootStorage.AddStream("C").SetData(bC); cf.RootStorage.AddStream("D").SetData(bD); cf.RootStorage.AddStream("E").SetData(bE); cf.RootStorage.AddStream("F").SetData(bF); cf.RootStorage.AddStream("G").SetData(bG); cf.RootStorage.AddStream("H").SetData(bH); cf.Save("8_Streams.cfs"); cf.Close(); // Test Phase 2 cfTest = new CompoundFile("8_Streams.cfs"); testSt = cfTest.RootStorage.GetStream("B"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bB.Length); Assert.IsTrue(Helpers.CompareBuffer(bB, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("C"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bC.Length); Assert.IsTrue(Helpers.CompareBuffer(bC, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("D"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bD.Length); Assert.IsTrue(Helpers.CompareBuffer(bD, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("E"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bE.Length); Assert.IsTrue(Helpers.CompareBuffer(bE, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("F"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bF.Length); Assert.IsTrue(Helpers.CompareBuffer(bF, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("G"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bG.Length); Assert.IsTrue(Helpers.CompareBuffer(bG, testSt.GetData())); testSt = cfTest.RootStorage.GetStream("H"); Assert.IsNotNull(testSt); Assert.IsTrue(testSt.Size == bH.Length); Assert.IsTrue(Helpers.CompareBuffer(bH, testSt.GetData())); cfTest.Close(); File.Copy("8_Streams.cfs", "6_Streams.cfs", true); File.Delete("8_Streams.cfs"); //########### // Phase 3 cf = new CompoundFile("6_Streams.cfs", UpdateMode.Update, true, true); cf.RootStorage.Delete("D"); cf.RootStorage.Delete("G"); cf.Commit(); cf.Close(); //Test Phase 3 cfTest = new CompoundFile("6_Streams.cfs"); bool catched = false; try { testSt = cfTest.RootStorage.GetStream("D"); } catch (Exception ex) { if (ex is CFItemNotFound) { catched = true; } } Assert.IsTrue(catched); catched = false; try { testSt = cfTest.RootStorage.GetStream("G"); } catch (Exception ex) { if (ex is CFItemNotFound) { catched = true; } } Assert.IsTrue(catched); cfTest.Close(); //########## // Phase 4 File.Copy("6_Streams.cfs", "6_Streams_Shrinked.cfs", true); CompoundFile.ShrinkCompoundFile("6_Streams_Shrinked.cfs"); // Test Phase 4 Assert.IsTrue(new FileInfo("6_Streams_Shrinked.cfs").Length < new FileInfo("6_Streams.cfs").Length); cfTest = new CompoundFile("6_Streams_Shrinked.cfs"); VisitedEntryAction va = delegate(ICFItem item) { if (item.IsStream) { ICFStream ia = item as ICFStream; Assert.IsNotNull(ia); Assert.IsTrue(ia.Size > 0); byte[] d = ia.GetData(); Assert.IsNotNull(d); Assert.IsTrue(d.Length > 0); Assert.IsTrue(d.Length == ia.Size); } }; cfTest.RootStorage.VisitEntries(va, true); cfTest.Close(); //########## //Phase 5 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStream("ZZZ").SetData(bF); cf.RootStorage.GetStream("E").AppendData(bE2); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.CLSID = new Guid("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStorage("MyStorage").AddStream("ANS").AppendData(bE); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStorage("AnotherStorage").AddStream("ANS").AppendData(bE); cf.RootStorage.Delete("MyStorage"); cf.Commit(); cf.Close(); //Test Phase 5 //##### //Phase 6 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.AddStorage("MiniStorage").AddStream("miniSt").AppendData(bMini); cf.RootStorage.GetStorage("MiniStorage").AddStream("miniSt2").AppendData(bMini); cf.Commit(); cf.Close(); cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.GetStorage("MiniStorage").Delete("miniSt"); cf.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").AppendData(bE); cf.Commit(); cf.Close(); //Test Phase 6 cfTest = new CompoundFile("6_Streams_Shrinked.cfs"); byte[] d2 = cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(); Assert.IsTrue(d2.Length == (bE.Length + bMini.Length)); int cnt = 1; d2 = cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(bMini.Length, ref cnt); Assert.IsTrue(cnt == 1); Assert.IsTrue(d2.Length == 1); Assert.IsTrue(d2[0] == 0x1A); cnt = 1; d2 = cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(bMini.Length - 1, ref cnt); Assert.IsTrue(cnt == 1); Assert.IsTrue(d2.Length == 1); Assert.IsTrue(d2[0] == 0xEE); try { cfTest.RootStorage.GetStorage("MiniStorage").GetStream("miniSt"); } catch (Exception ex) { Assert.IsTrue(ex is CFItemNotFound); } cfTest.Close(); //############## //Phase 7 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); cf.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").SetData(bA); cf.Commit(); cf.Close(); //Test Phase 7 cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.Update, true, false); d2 = cf.RootStorage.GetStorage("MiniStorage").GetStream("miniSt2").GetData(); Assert.IsNotNull(d2); Assert.IsTrue(d2.Length == bA.Length); cf.Close(); //############## cf = new CompoundFile("6_Streams_Shrinked.cfs", UpdateMode.ReadOnly, true, false); var myStream = cf.RootStorage.GetStream("C"); var data = myStream.GetData(); Console.WriteLine(data[0] + " : " + data[data.Length - 1]); myStream = cf.RootStorage.GetStream("B"); data = myStream.GetData(); Console.WriteLine(data[0] + " : " + data[data.Length - 1]); cf.Close(); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); }