/// <summary> /// This method returns all the transforms that are applied to a particular stream as an /// List of IDataTransform objects. /// </summary> /// <param name="streamInfo">StreamInfo for the stream whose transforms are requested</param> /// <returns>A List of IDataTransform objects that are applied to the stream represented by streamInfo</returns> internal List<IDataTransform> GetTransformsForStreamInfo(StreamInfo streamInfo) { string dataSpaces = this.DataSpaceOf(streamInfo.StreamReference); if (dataSpaces == null) // No datas pace is associated with the stream { return new List<IDataTransform>(0); // return an empty list } ArrayList transformsList = this.GetDataSpaceDefinition(dataSpaces).TransformStack; List<IDataTransform> dataTransforms = new List<IDataTransform>(transformsList.Count); for (int i = 0; i < transformsList.Count; i++) { dataTransforms.Add(this.GetTransformFromName(transformsList[i] as string)); } return dataTransforms; }
/// <summary> /// Read all transform definitions in one chunk /// </summary> // void ReadTransformDefinitions() { ThrowIfIncorrectReaderVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StorageInfo transformDefinitionsStorage = new StorageInfo( dataSpaceStorage, TransformDefinitions ); if( transformDefinitionsStorage.Exists ) { // Read transform definitions from file foreach( StorageInfo transformStorage in transformDefinitionsStorage.GetSubStorages() ) { // Read from primary stream StreamInfo transformPrimary = new StreamInfo( transformStorage, TransformPrimaryInfo ); using(Stream transformDefinition = transformPrimary.GetStream(FileMode.Open)) { using(BinaryReader definitionReader = new BinaryReader( transformDefinition, System.Text.Encoding.Unicode )) { int headerLength = definitionReader.ReadInt32(); // We don't actually do anything with HeaderLen at the moment int transformType = definitionReader.ReadInt32(); if (headerLength < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); // Create a TransformInstance class using name from file TransformInstance transformInstance = new TransformInstance(transformType, CU.ReadByteLengthPrefixedDWordPaddedUnicodeString( definitionReader ) ); int extraDataSize = checked ((int) (headerLength - transformDefinition.Position)); if (extraDataSize < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); if (extraDataSize > 0) { if (extraDataSize > AllowedExtraDataMaximumSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); // Preserve the fields we don't know about. byte[] extraData = definitionReader.ReadBytes(extraDataSize); if (extraData.Length != extraDataSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); transformInstance.ExtraData = extraData; } if( transformDefinition.Length > transformDefinition.Position ) { // We have additional data in the primary instance data stream int instanceDataSize = checked ((int)(transformDefinition.Length - transformDefinition.Position)); byte[] instanceData = new byte[instanceDataSize]; PackagingUtilities.ReliableRead(transformDefinition, instanceData, 0, instanceDataSize); //build memory stream on the byte[] , and allow writes only if // FileAccess is Write or ReadWrite MemoryStream instanceDataStream; if (_associatedStorage.OpenAccess == FileAccess.Read) { // NOTE: Building MemoryStream directly on top of // instanceData byte array because we want it to be // NOT resizable and NOT writable. instanceDataStream = new MemoryStream(instanceData, false /* Not writable */); } else { // Copy additional data into a memory stream // NOTE: Not building MemoryStream directly on top of // instanceData byte array because we want it to be // resizable. instanceDataStream = new MemoryStream(); instanceDataStream.Write( instanceData, 0, instanceDataSize ); } instanceDataStream.Seek( 0, SeekOrigin.Begin ); // Dirty state should be tracked after the original data is read in from the disk into the memory stream transformInstance.transformPrimaryStream = new DirtyStateTrackingStream(instanceDataStream); } transformInstance.transformStorage = transformStorage; SetTransformDefinition( transformStorage.Name, transformInstance ); } } } } }
/// <summary> /// Write out all transform definitions all at once /// </summary> /// // void WriteTransformDefinitions() { ThrowIfIncorrectUpdaterVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StorageInfo transformDefinitionsStorage = new StorageInfo( dataSpaceStorage, TransformDefinitions ); // if( 0 < _transformDefinitions.Count ) { foreach( string transformDef in _transformDefinitions.Keys ) { // 'transformDef' is the normalized label. We need to dig a // bit to retrieve the original transform label. string transformLabel = null; TransformInstance transformInstance = GetTransformInstanceOf( transformDef ); Debug.Assert( transformInstance != null, "A transform instance should be available if its name is in the transformDefinitions hashtable"); if( transformInstance.transformEnvironment != null ) { // We have a transform environment object - it has the transform label. transformLabel = transformInstance.transformEnvironment.TransformLabel; } else { // We don't have a transform environment object - we'll need to do a // more expensive reverse-lookup with the name manager. transformLabel = transformDef; } // Now use transformLabel to create the storage. StorageInfo singleTransformStorage = new StorageInfo( transformDefinitionsStorage, transformLabel ); StreamInfo transformPrimaryInfo = new StreamInfo( singleTransformStorage, TransformPrimaryInfo ); using(Stream transformPrimary = transformPrimaryInfo.GetStream()) { using(BinaryWriter transformWriter = new BinaryWriter( transformPrimary, System.Text.Encoding.Unicode )) { // Header length size = Known (the number itself + identifier) + // to be calculated (length of type name) int headerLength = checked (KnownBytesInTransformDefinitionHeader + CU.WriteByteLengthPrefixedDWordPaddedUnicodeString( null, transformInstance.typeName)); if (transformInstance.ExtraData != null) { Debug.Assert(transformInstance.ExtraData.Length > 0); checked { headerLength += transformInstance.ExtraData.Length; } } transformWriter.Write(headerLength); transformWriter.Write((int)TransformIdentifierTypes_PredefinedTransformName); CU.WriteByteLengthPrefixedDWordPaddedUnicodeString( transformWriter, transformInstance.typeName); // Write out the preserved unknown data if there are some if (transformInstance.ExtraData != null) { transformWriter.Write(transformInstance.ExtraData); } if( null != transformInstance.transformPrimaryStream ) { byte[] memoryBuffer = ((MemoryStream) ((DirtyStateTrackingStream) transformInstance.transformPrimaryStream).BaseStream).GetBuffer(); transformPrimary.Write( memoryBuffer, 0, memoryBuffer.Length ); } } } } } else // No transform definitions { if ( transformDefinitionsStorage.Exists) { dataSpaceStorage.Delete(true, TransformDefinitions); //transformDefinitionStorage.Delete(true); } } }
/// <summary> /// Converts the byte data from a StreamInfo Package stream to /// ASCII string data. /// </summary> /// <param name="streamInfo">The StreamInfo Package the data is read from.</param> /// <returns>A ASCII string of the byte data is returned.</returns> /// <remarks>The underlying stream is opened in Read Only mode using a /// Stream object.</remarks> public static string ConvertStreamBytesToASCII(StreamInfo streamInfo) { byte[] streamData = null; try { using(Stream streamReader = streamInfo.GetStream(FileMode.Open, FileAccess.Read)) { streamData = new byte[streamReader.Length]; streamReader.Read(streamData, 0, streamData.Length); return ASCIIEncoding.ASCII.GetString(streamData); } } catch(Exception ex) { throw ex; } finally { streamData = null; } }
/// <summary> /// Write all data space definitions to underlying storage in one chunk. /// </summary> /// // void WriteDataSpaceDefinitions() { ThrowIfIncorrectUpdaterVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); // // Write out data space definitions if( 0 < _dataSpaceDefinitions.Count ) { StorageInfo dataSpaceDefinitionsStorage = new StorageInfo(dataSpaceStorage, DataSpaceDefinitionsStorageName); dataSpaceDefinitionsStorage.Create(); foreach( string name in _dataSpaceDefinitions.Keys ) { StreamInfo singleDefinitionInfo = new StreamInfo(dataSpaceDefinitionsStorage,name); using(Stream singleDefinition = singleDefinitionInfo.GetStream()) { using(BinaryWriter definitionWriter =new BinaryWriter( singleDefinition, System.Text.Encoding.Unicode )) { DataSpaceDefinition definition = (DataSpaceDefinition) _dataSpaceDefinitions[name]; int headerSize = KnownBytesInDataSpaceDefinitionHeader; if (definition.ExtraData != null) { checked { headerSize += definition.ExtraData.Length; } } definitionWriter.Write( headerSize ); definitionWriter.Write( definition.TransformStack.Count ); if (definition.ExtraData != null) { definitionWriter.Write(definition.ExtraData); } foreach( object transformLabel in definition.TransformStack) { CU.WriteByteLengthPrefixedDWordPaddedUnicodeString( definitionWriter, (string)transformLabel); } } } } } }
/***********************************************************************/ // public Methods /// <summary> /// Creates "this" stream /// </summary> /// <param name="name">Name of stream</param> /// <param name="compressionOption">CompressionOptiont</param> /// <param name="encryptionOption">EncryptionOption</param> /// <returns>Reference to new stream</returns> public StreamInfo CreateStream( string name, CompressionOption compressionOption, EncryptionOption encryptionOption ) { CheckDisposedStatus(); //check the arguments if( null == name ) throw new ArgumentNullException("name"); // Stream names: we preserve casing, but do case-insensitive comparison (Native CompoundFile API behavior) if (((IEqualityComparer) CU.StringCaseInsensitiveComparer).Equals(name, EncryptedPackageEnvelope.PackageStreamName)) throw new ArgumentException(SR.Get(SRID.StreamNameNotValid,name)); //create a new streaminfo object StreamInfo streamInfo = new StreamInfo(this, name, compressionOption, encryptionOption); if (streamInfo.InternalExists()) { throw new IOException(SR.Get(SRID.StreamAlreadyExist)); } //Define the compression and encryption options in the dataspacemanager DataSpaceManager manager = Root.GetDataSpaceManager(); string dataSpaceLabel = null; if (manager != null) { //case : Compression option is set. Stream need to be compressed. Define compression transform. //At this time, we only treat CompressionOption - Normal and None. The rest are treated as Normal if (compressionOption != CompressionOption.NotCompressed) { //If it is not defined already, define it. if (!manager.TransformLabelIsDefined(sc_compressionTransformName)) manager.DefineTransform(CompressionTransform.ClassTransformIdentifier, sc_compressionTransformName); } //case : Encryption option is set. Stream need to be encrypted. Define encryption transform. if (encryptionOption == EncryptionOption.RightsManagement) { //If it not defined already, define it. if (!manager.TransformLabelIsDefined(EncryptedPackageEnvelope.EncryptionTransformName)) { //We really cannot define RM transform completely here because the transform initialization cannot be done here without publishlicense and cryptoprovider. //However it will always be defined because this method is accessed only through an EncryptedPackageEnvelope and RM transform is always defined in EncryptedPackageEnvelope.Create() throw new SystemException(SR.Get(SRID.RightsManagementEncryptionTransformNotFound)); } } //Now find the dataspace label that we need to define these transforms in. //CASE: When both CompressionOption and EncryptionOption are set if ( (compressionOption != CompressionOption.NotCompressed) && (encryptionOption == EncryptionOption.RightsManagement) ) { dataSpaceLabel = sc_dataspaceLabelRMEncryptionNormalCompression; if (!manager.DataSpaceIsDefined(dataSpaceLabel)) { string[] transformStack = new string[2]; //compress the data first. then encrypt it. This ordering will cause the content to be compressed, then encrypted, then written to the stream. transformStack[0] = EncryptedPackageEnvelope.EncryptionTransformName; transformStack[1] = sc_compressionTransformName; manager.DefineDataSpace(transformStack, dataSpaceLabel); } } //CASE : when CompressionOption alone is set else if ( (compressionOption != CompressionOption.NotCompressed) && (encryptionOption == EncryptionOption.None) ) { dataSpaceLabel = sc_dataspaceLabelNoEncryptionNormalCompression; if (!manager.DataSpaceIsDefined(dataSpaceLabel)) { string[] transformStack = new string[1]; transformStack[0] = sc_compressionTransformName; manager.DefineDataSpace(transformStack, dataSpaceLabel); } } //CASE : when EncryptionOption alone is set else if (encryptionOption == EncryptionOption.RightsManagement) { dataSpaceLabel = EncryptedPackageEnvelope.DataspaceLabelRMEncryptionNoCompression; if (!manager.DataSpaceIsDefined(dataSpaceLabel)) { string[] transformStack = new string[1]; transformStack[0] = EncryptedPackageEnvelope.EncryptionTransformName; manager.DefineDataSpace(transformStack, dataSpaceLabel); } } //All the other cases are not handled at this point. } //create the underlying stream if (null == dataSpaceLabel) streamInfo.Create(); //create the stream with default parameters else streamInfo.Create(dataSpaceLabel); //create the stream in the defined dataspace return streamInfo; }
/// <summary> /// Check if the stream exists. /// </summary> /// <param name="name">Name of stream</param> /// <returns>True if exists, False if not</returns> public bool StreamExists(string name) { CheckDisposedStatus(); bool streamExists = false; StreamInfo streamInfo = new StreamInfo(this, name); streamExists = streamInfo.InternalExists(); return streamExists; }
DeleteUseLicenseForUser( RightsManagementEncryptionTransform rmet, StreamInfo si, object param, ref bool stop ) { ContentUser userToDelete = param as ContentUser; if (userToDelete == null) { throw new ArgumentException(SR.Get(SRID.CallbackParameterInvalid), "param"); } ContentUser userFromStream = null; using (Stream stream = si.GetStream(FileMode.Open, FileAccess.Read)) { using (BinaryReader utf8Reader = new BinaryReader(stream, Encoding.UTF8)) { userFromStream = rmet.LoadUserFromStream(utf8Reader); } } if (userFromStream.GenericEquals(userToDelete)) { si.Delete(); } }
SaveUseLicenseForUser( ContentUser user, UseLicense useLicense ) { // // Generate a unique name for the use license stream, and create the stream. // string useLicenseStreamName = MakeUseLicenseStreamName(); StreamInfo si = new StreamInfo(_useLicenseStorage, useLicenseStreamName); // This guarantees a call to Stream.Dispose, which is equivalent to Stream.Close. using (Stream licenseStream = si.Create()) { // Create a BinaryWriter on the stream. using (BinaryWriter utf8Writer = new BinaryWriter(licenseStream, Encoding.UTF8)) { // // Construct a type-prefixed user name of the form // "Passport:[....][email protected]" or "Windows:domain\username", // depending on the authentication type of the user. // string typePrefixedUserName = MakeTypePrefixedUserName(user); // // For compatibility with Office, Base64 encode the type-prefixed user name // for the sake of some minimal obfuscation. The parameters to the // UnicodeEncoding ctor mean: "UTF-16 little-endian, no byte order mark". // Then convert the Base64 characters to UTF-8 encoding. // byte [] userNameBytes = _unicodeEncoding.GetBytes(typePrefixedUserName); string base64UserName = Convert.ToBase64String(userNameBytes); byte [] utf8Bytes = Encoding.UTF8.GetBytes(base64UserName); Int32 utf8ByteLength = utf8Bytes.Length; // // Write out a header preceding the use license. The header is of the form: // Int32 headerLength // Int32 userNameLength (in bytes) // Byte userName[userNameLength] // Byte paddings Int32 headerLength = checked ( 2 * CU.Int32Size + utf8ByteLength + CU.CalculateDWordPadBytesLength(utf8ByteLength)); utf8Writer.Write(headerLength); utf8Writer.Write(utf8ByteLength); utf8Writer.Write(utf8Bytes, 0, utf8ByteLength); WriteDwordPadding(utf8ByteLength, utf8Writer); // // Write out the use license itself. // WriteByteLengthPrefixedDwordPaddedString(useLicense.ToString(), utf8Writer, Encoding.UTF8); } } }
AddUseLicenseFromStreamToDictionary( RightsManagementEncryptionTransform rmet, StreamInfo si, object param, ref bool stop ) { ContentUser user; using (Stream stream = si.GetStream(FileMode.Open, FileAccess.Read)) { using(BinaryReader utf8Reader = new BinaryReader(stream, _utf8Encoding)) { UseLicense useLicense = rmet.LoadUseLicenseAndUserFromStream(utf8Reader, out user); _dict.Add(user, useLicense); } } }
LoadUseLicenseForUser( RightsManagementEncryptionTransform rmet, StreamInfo si, object param, ref bool stop ) { LoadUseLicenseForUserParams lulfup = param as LoadUseLicenseForUserParams; if (lulfup == null) { throw new ArgumentException(SR.Get(SRID.CallbackParameterInvalid), "param"); } ContentUser userDesired = lulfup.User; Debug.Assert(userDesired != null); ContentUser userFromStream = null; using (Stream stream = si.GetStream(FileMode.Open, FileAccess.Read)) { using (BinaryReader utf8Reader = new BinaryReader(stream, Encoding.UTF8)) { userFromStream = rmet.LoadUserFromStream(utf8Reader); if (userFromStream.GenericEquals(userDesired)) { lulfup.UseLicense = rmet.LoadUseLicenseFromStream(utf8Reader); stop = true; } } } }
/// <summary> /// Retrieve the package stream contained in the compound file. /// </summary> private void EnsurePackageStream() { if (_packageStream == null) { StreamInfo siPackage = new StreamInfo(_root, PackageStreamName); if (siPackage.InternalExists()) { // // Open the existing package stream with the same level of access // that the compound file is open. // _packageStream = siPackage.GetStream(FileMode.Open, this.FileOpenAccess); } else { //Error. This package is created in InitForCreate while creating EncryptedPackageEnvelope. //If it does not exist, throw an error. throw new FileFormatException(SR.Get(SRID.PackageNotFound)); } } }
InitForOpen() { StreamInfo siPackage = new StreamInfo(_root, PackageStreamName); if (!siPackage.InternalExists()) { throw new FileFormatException(SR.Get(SRID.PackageNotFound)); } //If the StreamInfo exists we go on to check if correct transform has been //applied to the Stream DataSpaceManager dsm = _root.GetDataSpaceManager(); List<IDataTransform> transforms = dsm.GetTransformsForStreamInfo(siPackage); RightsManagementEncryptionTransform rmet = null; foreach (IDataTransform dataTransform in transforms) { string id = dataTransform.TransformIdentifier as string; if (id != null && String.CompareOrdinal(id.ToUpperInvariant(), RightsManagementEncryptionTransform.ClassTransformIdentifier.ToUpperInvariant()) == 0) { // Do not allow more than one RM Transform if (rmet != null) { throw new FileFormatException(SR.Get(SRID.MultipleRightsManagementEncryptionTransformFound)); } rmet = dataTransform as RightsManagementEncryptionTransform; } } if (rmet == null) { throw new FileFormatException(SR.Get(SRID.RightsManagementEncryptionTransformNotFound)); } // // There is no reason to further push initialization of the Rights Management // data (parsing publish / use license). It will add unnecessary costs to the // scenarios where RM license are not relevant, for example indexing and // working with document properties // // // Make the rights management information stored in the compound file // available to the application through the RightsManagementInformation // property. // _rmi = new RightsManagementInformation(rmet); }
EmbedPackage(Stream packageStream) { StreamInfo siPackage = new StreamInfo(_root, PackageStreamName); Debug.Assert(!siPackage.InternalExists()); // // Create a stream to hold the document content. Create it in the // dataspace containing the RightsManagementEncryptionTransform. This // will cause the compound file code (specifically, the DataSpaceManager) // to create a RightsManagementEncryptionTransform object, and then // to trigger the TransformInitializationEvent, which will allow us to // retrieve the transform object. // _packageStream = siPackage.Create( FileMode.Create, _root.OpenAccess, _dataSpaceName ); if (packageStream != null) { //copy the stream PackagingUtilities.CopyStream(packageStream, _packageStream, Int64.MaxValue, /*bytes to copy*/ 4096 /*buffer size */); _package = Package.Open(_packageStream, FileMode.Open, this.FileOpenAccess); } else { // // Create the package on the package stream // _package = Package.Open(_packageStream, FileMode.Create, FileAccess.ReadWrite); _package.Flush(); _packageStream.Flush(); } }
// Constructors internal CFStream( IStream underlyingStream, FileAccess openAccess, StreamInfo creator) { _safeIStream = underlyingStream; access = openAccess; backReference = creator; }
Stream BuildStreamOnUnderlyingIStream( IStream underlyingIStream, FileAccess access, StreamInfo parent ) { Stream rawStream = new CFStream( underlyingIStream, access, parent ); if( null == core.dataSpaceLabel ) { // The stream is not transformed in any data space, add buffering and return return new BufferedStream( rawStream ); } else { // Pass raw stream to data space manager to get real stream return parentStorage.Root.GetDataSpaceManager().CreateDataSpaceStream( StreamReference, rawStream); } }
private byte[] ParsePreviewInfo(StreamInfo streamInfo) { byte[] streamData = null; try { using(Stream streamReader = streamInfo.GetStream(FileMode.Open, FileAccess.Read)) { streamData = new byte[streamReader.Length]; streamReader.Read(streamData, 0, streamData.Length); return streamData; } } catch(Exception ex) { throw ex; } finally { streamData = null; } }
/// <summary> /// Reads a data space map from the associated container, if such a thing /// is written to the file. /// </summary> void ReadDataSpaceMap() { // See if there's even a data spaces storage StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StreamInfo dataSpaceMapStreamInfo = new StreamInfo( dataSpaceStorage, DataSpaceMapTableName ); if( dataSpaceStorage.StreamExists(DataSpaceMapTableName) ) { // There is an existing data space mapping table to read. // Read the versioning information ReadDataSpaceVersionInformation(dataSpaceStorage); // Check if its the correct version for reading ThrowIfIncorrectReaderVersion(); // Read the data space mapping table using(Stream dataSpaceMapStream = dataSpaceMapStreamInfo.GetStream(FileMode.Open)) { using(BinaryReader dataSpaceMapReader = new BinaryReader( dataSpaceMapStream, System.Text.Encoding.Unicode )) { int headerLength = dataSpaceMapReader.ReadInt32(); int entryCount = dataSpaceMapReader.ReadInt32(); if (headerLength < KnownBytesInMapTableHeader || entryCount < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); int extraDataSize = headerLength - KnownBytesInMapTableHeader; if( 0 < extraDataSize ) { if (extraDataSize > AllowedExtraDataMaximumSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); _mapTableHeaderPreservation = dataSpaceMapReader.ReadBytes(extraDataSize); if (_mapTableHeaderPreservation.Length != extraDataSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); } _dataSpaceMap.Capacity = entryCount; int entryLength; int bytesRead; int totalBytesRead; for( int i = 0; i < entryCount; i++ ) { entryLength = dataSpaceMapReader.ReadInt32(); if (entryLength < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); totalBytesRead = 4; // entryLength // Read the container reference entry CompoundFileReference entryRef = CompoundFileReference.Load( dataSpaceMapReader, out bytesRead ); checked { totalBytesRead += bytesRead; } // Read data space string and add to data space mapping table string label = CU.ReadByteLengthPrefixedDWordPaddedUnicodeString(dataSpaceMapReader, out bytesRead); checked { totalBytesRead += bytesRead; } _dataSpaceMap[entryRef] = label; // Verify entryLength against what was actually read: if (entryLength != totalBytesRead) { throw new IOException(SR.Get(SRID.DataSpaceMapEntryInvalid)); } } } } } }
/// <summary> /// Returns the streaminfo by the passed name. /// </summary> /// <param name="name">Name of stream</param> /// <returns>Reference to the stream</returns> public StreamInfo GetStreamInfo(string name) { CheckDisposedStatus(); //check the arguments if( null == name ) throw new ArgumentNullException("name"); StreamInfo streamInfo = new StreamInfo(this, name); if (streamInfo.InternalExists()) { return streamInfo; } else { throw new IOException(SR.Get(SRID.StreamNotExist)); } }
/// <summary> /// Write the data space mapping table to underlying storage. /// </summary> void WriteDataSpaceMap() { ThrowIfIncorrectUpdaterVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StreamInfo dataSpaceMapStreamInfo = new StreamInfo ( dataSpaceStorage, DataSpaceMapTableName ); if( 0 < _dataSpaceMap.Count ) { // Write versioning information StreamInfo versionStreamInfo = null; if (dataSpaceStorage.StreamExists( DataSpaceVersionName ) ) versionStreamInfo = dataSpaceStorage.GetStreamInfo( DataSpaceVersionName ); else versionStreamInfo = dataSpaceStorage.CreateStream( DataSpaceVersionName ); Stream versionStream = versionStreamInfo.GetStream(); _fileFormatVersion.SaveToStream(versionStream); versionStream.Close(); // Create stream for write, overwrite any existing using(Stream dataSpaceMapStream = dataSpaceMapStreamInfo.GetStream(FileMode.Create)) { using(BinaryWriter dataSpaceMapWriter = new BinaryWriter( dataSpaceMapStream, System.Text.Encoding.Unicode )) { // Write header // header length = our known size + preserved array size dataSpaceMapWriter.Write( checked ((Int32) (KnownBytesInMapTableHeader + _mapTableHeaderPreservation.Length))); // number of entries dataSpaceMapWriter.Write( _dataSpaceMap.Count ); // anything else we've preserved dataSpaceMapWriter.Write( _mapTableHeaderPreservation ); // Loop to write entries foreach( CompoundFileReference o in _dataSpaceMap.Keys ) { // determine the entry length string label = (string)_dataSpaceMap[o]; int entryLength = CompoundFileReference.Save(o, null); checked { entryLength += CU.WriteByteLengthPrefixedDWordPaddedUnicodeString(null, label); } // length of entryLength itself checked { entryLength += 4; } // write out the entry length dataSpaceMapWriter.Write((Int32) entryLength); // Write out reference CompoundFileReference.Save( o, dataSpaceMapWriter); // Write out dataspace label CU.WriteByteLengthPrefixedDWordPaddedUnicodeString( dataSpaceMapWriter, label); } } } } else { // data space map is empty, remove existing stream if there. if ( dataSpaceStorage.StreamExists( DataSpaceMapTableName ) ) dataSpaceStorage.DeleteStream( DataSpaceMapTableName ); } }
/// <summary> /// Deleted the stream with the passed name. /// </summary> /// <param name="name">Name of stream</param> public void DeleteStream(string name) { CheckDisposedStatus(); //check the arguments if( null == name ) throw new ArgumentNullException("name"); StreamInfo streamInfo = new StreamInfo(this, name); if (streamInfo.InternalExists()) { streamInfo.Delete(); } }
/// <summary> /// Converts the byte data from a StreamInfo Package stream to /// HEX string data. /// </summary> /// <param name="streamInfo">The StreamInfo Package the data is read from.</param> /// <returns>A HEX string of the byte data is returned.</returns> /// <remarks>The underlying stream is opened in Read Only mode using a /// Stream object.</remarks> public static string ConvertStreamBytesToHex(StreamInfo streamInfo) { StringBuilder sb = new StringBuilder(); string convertedValue = string.Empty; try { using(Stream streamReader = streamInfo.GetStream(FileMode.Open, FileAccess.Read)) { int currentRead; while((currentRead = streamReader.ReadByte()) >= 0) { byte currentByte = (byte)currentRead; sb.AppendFormat("{0:X2}", currentByte); } convertedValue = sb.ToString(); return convertedValue; } } catch (Exception ex) { throw ex; } finally { sb.Length = 0; sb.Capacity = 0; sb = null; } }