Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / System / IO / Packaging / CompoundFile / StorageRoot.cs / 1305600 / StorageRoot.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // The root object for manipulating the WPP container. // // History: // 05/10/2002: RogerCh: Initial creation. // 06/12/2002: RogerCh: Catch & translate COMException from native calls. // 06/25/2002: RogerCh: Add a constructor to build on top of IStorage. // 06/28/2002: RogerCh: Add a boolean to avoid infinite loops in data space // manager initialization. // 07/31/2002: RogerCh: Make obvious that we are using security suppressed interfaces. // 05/20/2003: RogerCh: Ported to WCP tree. // //----------------------------------------------------------------------------- using System; using System.IO; using System.Runtime.InteropServices; using System.Windows; // For exception string lookup table using MS.Internal; // for Invariant using MS.Internal.IO.Packaging.CompoundFile; using MS.Internal.WindowsBase; namespace System.IO.Packaging { ////// The main container class, one instance per compound file /// internal class StorageRoot : StorageInfo { /***********************************************************************/ // Default values to use for the StorageRoot.Open shortcuts const FileMode defaultFileMode = FileMode.OpenOrCreate; const FileAccess defaultFileAccess = FileAccess.ReadWrite; const FileShare defaultFileShare = FileShare.None; const int defaultSectorSize = 512; const int stgFormatDocFile = 5; // STGFMT_DOCFILE /***********************************************************************/ // Instance values ////// The reference to the IStorage root of this container. This value /// is initialized at Open and zeroed out at Close. If this value is /// zero, it means the object has been disposed. /// IStorage rootIStorage; ////// Cached instance to our data space manager /// DataSpaceManager dataSpaceManager; ////// If we know we are in a read-only mode, we know not to do certain things. /// bool containerIsReadOnly; ////// When data space manager is being initialized, sometimes it trips /// actions that would (in other circumstances) require checking the /// data space manager. To avoid an infinite loop, we break it by knowing /// when data space manager is being initialized. /// bool dataSpaceManagerInitializationInProgress; /***********************************************************************/ private StorageRoot(IStorage root, bool readOnly ) : base( root ) { rootIStorage = root; containerIsReadOnly = readOnly; dataSpaceManagerInitializationInProgress = false; } ////// The access mode available on this container /// internal FileAccess OpenAccess { get { CheckRootDisposedStatus(); if(containerIsReadOnly) { return FileAccess.Read; } else { return FileAccess.ReadWrite; } } } ////// Create a container StorageRoot based on the given System.IO.Stream object /// /// The new Stream upon which to build the new StorageRoot ///New StorageRoot object built on the given Stream internal static StorageRoot CreateOnStream( Stream baseStream ) { if (baseStream == null) { throw new ArgumentNullException("baseStream"); } if( 0 == baseStream.Length ) { return CreateOnStream( baseStream, FileMode.Create ); } else { return CreateOnStream( baseStream, FileMode.Open ); } } ////// Create a container StorageRoot based on the given System.IO.Stream object /// /// The new Stream upon which to build the new StorageRoot /// The mode (Open or Create) to use on the lock bytes ///New StorageRoot object built on the given Stream internal static StorageRoot CreateOnStream(Stream baseStream, FileMode mode) { if( null == baseStream ) throw new ArgumentNullException("baseStream"); IStorage storageOnStream; int returnValue; int openFlags = SafeNativeCompoundFileConstants.STGM_SHARE_EXCLUSIVE; if( baseStream.CanRead ) { if( baseStream.CanWrite ) { openFlags |= SafeNativeCompoundFileConstants.STGM_READWRITE; } else { openFlags |= SafeNativeCompoundFileConstants.STGM_READ; if( FileMode.Create == mode ) throw new ArgumentException( SR.Get(SRID.CanNotCreateContainerOnReadOnlyStream)); } } else { throw new ArgumentException( SR.Get(SRID.CanNotCreateStorageRootOnNonReadableStream)); } if( FileMode.Create == mode ) { returnValue = SafeNativeCompoundFileMethods.SafeStgCreateDocfileOnStream( baseStream, openFlags | SafeNativeCompoundFileConstants.STGM_CREATE, out storageOnStream); } else if( FileMode.Open == mode ) { returnValue = SafeNativeCompoundFileMethods.SafeStgOpenStorageOnStream( baseStream, openFlags, out storageOnStream ); } else { throw new ArgumentException( SR.Get(SRID.CreateModeMustBeCreateOrOpen)); } switch( (uint) returnValue ) { case SafeNativeCompoundFileConstants.S_OK: return StorageRoot.CreateOnIStorage( storageOnStream ); default: throw new IOException( SR.Get(SRID.UnableToCreateOnStream), new COMException( SR.Get(SRID.CFAPIFailure), returnValue)); } } ///Open a container, given only the path. /// Path to container file on local file system ///StorageRoot instance representing the file internal static StorageRoot Open( string path ) { return Open( path, defaultFileMode, defaultFileAccess, defaultFileShare, defaultSectorSize ); } ///Open a container, given path and open mode /// Path to container file on local file system /// Access mode, see System.IO.FileMode in .NET SDK ///StorageRoot instance representing the file internal static StorageRoot Open( string path, FileMode mode ) { return Open( path, mode, defaultFileAccess, defaultFileShare, defaultSectorSize ); } ///Open a container, given path, open mode, and access flag /// Path to container file on local file system /// See System.IO.FileMode in .NET SDK /// See System.IO.FileAccess in .NET SDK ///StorageRoot instance representing the file internal static StorageRoot Open( string path, FileMode mode, FileAccess access ) { return Open( path, mode, access, defaultFileShare, defaultSectorSize ); } ///Open a container, given path, open mode, access flag, and sharing settings /// Path to container on local file system /// See System.IO.FileMode in .NET SDK /// See System.IO.FileAccess in .NET SDK /// See System.IO.FileSharing in .NET SDK ///StorageRoot instance representing the file internal static StorageRoot Open( string path, FileMode mode, FileAccess access, FileShare share ) { return Open( path, mode, access, share, defaultSectorSize ); } ///Open a container given all the settings /// Path to container on local file system /// See System.IO.FileMode in .NET SDK /// See System.IO.FileAccess in .NET SDK /// See System.IO.FileShare in .NET SDK /// Compound File sector size, must be 512 or 4096 ///StorageRoot instance representing the file internal static StorageRoot Open( string path, FileMode mode, FileAccess access, FileShare share, int sectorSize ) { int grfMode = 0; int returnValue = 0; // Simple path validation ContainerUtilities.CheckStringAgainstNullAndEmpty( path, "Path" ); Guid IID_IStorage = new Guid(0x0000000B,0x0000,0x0000,0xC0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46); IStorage newRootStorage; //////////////////////////////////////////////////////////////////// // Generate STGM from FileMode switch(mode) { case FileMode.Append: throw new ArgumentException( SR.Get(SRID.FileModeUnsupported)); case FileMode.Create: grfMode |= SafeNativeCompoundFileConstants.STGM_CREATE; break; case FileMode.CreateNew: { FileInfo existTest = new FileInfo(path); if( existTest.Exists ) { throw new IOException( SR.Get(SRID.FileAlreadyExists)); } } goto case FileMode.Create; case FileMode.Open: break; case FileMode.OpenOrCreate: { FileInfo existTest = new FileInfo(path); if( existTest.Exists ) { // File exists, use open code path goto case FileMode.Open; } else { // File does not exist, use create code path goto case FileMode.Create; } } case FileMode.Truncate: throw new ArgumentException( SR.Get(SRID.FileModeUnsupported)); default: throw new ArgumentException( SR.Get(SRID.FileModeInvalid)); } // Generate the access flags from the access parameter SafeNativeCompoundFileMethods.UpdateModeFlagFromFileAccess( access, ref grfMode ); // Generate STGM from FileShare // Note: the .NET SDK does not specify the proper behavior in reaction to // incompatible flags being sent in together. Should ArgumentException be // thrown? Or do some values "trump" others? if( 0 != (share & FileShare.Inheritable) ) { throw new ArgumentException( SR.Get(SRID.FileShareUnsupported)); } else if( share == FileShare.None ) // FileShare.None is zero, using "&" to check causes unreachable code error { grfMode |= SafeNativeCompoundFileConstants.STGM_SHARE_EXCLUSIVE; } else if( share == FileShare.Read ) { grfMode |= SafeNativeCompoundFileConstants.STGM_SHARE_DENY_WRITE; } else if( share == FileShare.Write ) { grfMode |= SafeNativeCompoundFileConstants.STGM_SHARE_DENY_READ; // Note that this makes little sense when we don't support combination of flags } else if( share == FileShare.ReadWrite ) { grfMode |= SafeNativeCompoundFileConstants.STGM_SHARE_DENY_NONE; } else { throw new ArgumentException( SR.Get(SRID.FileShareInvalid)); } if( 0 != (grfMode & SafeNativeCompoundFileConstants.STGM_CREATE)) { // STGM_CREATE set, call StgCreateStorageEx. returnValue = SafeNativeCompoundFileMethods.SafeStgCreateStorageEx( path, grfMode, stgFormatDocFile, 0, IntPtr.Zero, IntPtr.Zero, ref IID_IStorage, out newRootStorage ); } else { // STGM_CREATE not set, call StgOpenStorageEx. returnValue = SafeNativeCompoundFileMethods.SafeStgOpenStorageEx( path, grfMode, stgFormatDocFile, 0, IntPtr.Zero, IntPtr.Zero, ref IID_IStorage, out newRootStorage ); } switch( returnValue ) { case SafeNativeCompoundFileConstants.S_OK: return StorageRoot.CreateOnIStorage( newRootStorage ); case SafeNativeCompoundFileConstants.STG_E_FILENOTFOUND: throw new FileNotFoundException( SR.Get(SRID.ContainerNotFound)); case SafeNativeCompoundFileConstants.STG_E_INVALIDFLAG: throw new ArgumentException( SR.Get(SRID.StorageFlagsUnsupported), new COMException( SR.Get(SRID.CFAPIFailure), returnValue)); default: throw new IOException( SR.Get(SRID.ContainerCanNotOpen), new COMException( SR.Get(SRID.CFAPIFailure), returnValue)); } } ////// Clean up this container storage instance /// internal void Close() { if( null == rootIStorage ) return; // Extraneous calls to Close() are ignored if( null != dataSpaceManager ) { // Tell data space manager to flush all information as necessary dataSpaceManager.Dispose(); dataSpaceManager = null; } try { // Shut down the underlying storage if( !containerIsReadOnly ) rootIStorage.Commit(0); } finally { // We need these clean up steps to run even if there's a problem // with the commit above. RecursiveStorageInfoCoreRelease( core ); rootIStorage = null; } } ////// Flush the storage root. /// internal void Flush() { CheckRootDisposedStatus(); // Shut down the underlying storage if( !containerIsReadOnly ) rootIStorage.Commit(0); } ////// Obtains the data space manager object for this instance of the /// container. Subsequent calls will return reference to the same /// object. /// ///Reference to the manager object internal DataSpaceManager GetDataSpaceManager() { CheckRootDisposedStatus(); if( null == dataSpaceManager ) { if ( dataSpaceManagerInitializationInProgress ) return null; // initialization in progress - abort // Create new instance of data space manager dataSpaceManagerInitializationInProgress = true; dataSpaceManager = new DataSpaceManager( this ); dataSpaceManagerInitializationInProgress = false; } return dataSpaceManager; } internal IStorage GetRootIStorage() { return rootIStorage; } // Check whether this StorageRoot class still has its underlying storage. // If not, throw an object disposed exception. This should be checked from // every non-static container external API. internal void CheckRootDisposedStatus() { if( RootDisposed ) throw new ObjectDisposedException(null, SR.Get(SRID.StorageRootDisposed)); } // Check whether this StorageRoot class still has its underlying storage. internal bool RootDisposed { get { return ( null == rootIStorage ); } } ////// This will create a container StorageRoot based on the given IStorage /// interface /// /// The new IStorage (RCW) upon which to build the new StorageRoot ///New StorageRoot object built on the given IStorage private static StorageRoot CreateOnIStorage( IStorage root ) { // The root is created by calling unmanaged CompoundFile APIs. The return value from the call is always // checked to see if is S_OK. If it is S_OK, the root should never be null. However, just to make sure // call Invariant.Assert Invariant.Assert(root != null); System.Runtime.InteropServices.ComTypes.STATSTG rootSTAT; bool readOnly; root.Stat( out rootSTAT, SafeNativeCompoundFileConstants.STATFLAG_NONAME ); readOnly =( SafeNativeCompoundFileConstants.STGM_WRITE != ( rootSTAT.grfMode & SafeNativeCompoundFileConstants.STGM_WRITE ) && SafeNativeCompoundFileConstants.STGM_READWRITE != (rootSTAT.grfMode & SafeNativeCompoundFileConstants.STGM_READWRITE) ); return new StorageRoot( root, readOnly ); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExtendedProtectionPolicy.cs
- ScriptResourceAttribute.cs
- BypassElementCollection.cs
- KnownBoxes.cs
- PermissionRequestEvidence.cs
- Expr.cs
- WebPartCancelEventArgs.cs
- SQLMoneyStorage.cs
- DynamicArgumentDesigner.xaml.cs
- HashCodeCombiner.cs
- MissingMethodException.cs
- SequenceDesignerAccessibleObject.cs
- Adorner.cs
- BaseTreeIterator.cs
- HttpResponse.cs
- SettingsPropertyValueCollection.cs
- MatrixConverter.cs
- LoggedException.cs
- SynchronizationScope.cs
- Stream.cs
- WebPartZoneCollection.cs
- BoundPropertyEntry.cs
- XmlAtomicValue.cs
- SqlCacheDependencyDatabase.cs
- LocationUpdates.cs
- UrlMapping.cs
- GenericUriParser.cs
- SQLInt32Storage.cs
- ListViewItemMouseHoverEvent.cs
- CodeTypeReferenceCollection.cs
- ProfilePropertySettingsCollection.cs
- DiscoveryService.cs
- RawKeyboardInputReport.cs
- TrustLevel.cs
- SelectedDatesCollection.cs
- ServiceDiscoveryBehavior.cs
- PropertyManager.cs
- ZoneButton.cs
- tibetanshape.cs
- HMACSHA512.cs
- RichTextBoxAutomationPeer.cs
- MatrixCamera.cs
- ColumnBinding.cs
- PointAnimationBase.cs
- DataGridViewColumnTypeEditor.cs
- FrameworkElementFactory.cs
- CodeDOMUtility.cs
- XmlWrappingReader.cs
- FloatSumAggregationOperator.cs
- LongSumAggregationOperator.cs
- ipaddressinformationcollection.cs
- TextEditorMouse.cs
- connectionpool.cs
- GridItemCollection.cs
- TargetConverter.cs
- WsdlHelpGeneratorElement.cs
- ReferenceEqualityComparer.cs
- ArraySortHelper.cs
- Object.cs
- ImmutableObjectAttribute.cs
- InternalUserCancelledException.cs
- SettingsBindableAttribute.cs
- UseLicense.cs
- DataServices.cs
- InternalDuplexChannelFactory.cs
- MostlySingletonList.cs
- DesignerLoader.cs
- MenuStrip.cs
- DefaultValueAttribute.cs
- DirectoryNotFoundException.cs
- NetStream.cs
- ThrowOnMultipleAssignment.cs
- XsltCompileContext.cs
- OutputCacheSection.cs
- RootAction.cs
- Quaternion.cs
- DebugController.cs
- DependencyPropertyConverter.cs
- UInt16Converter.cs
- ObjectStateEntryDbDataRecord.cs
- GenericsInstances.cs
- StorageFunctionMapping.cs
- ReadOnlyDataSourceView.cs
- AncestorChangedEventArgs.cs
- IImplicitResourceProvider.cs
- SqlMetaData.cs
- MultiBindingExpression.cs
- ObjectStateEntryDbDataRecord.cs
- ObjectKeyFrameCollection.cs
- XPathNavigator.cs
- WorkflowQueueInfo.cs
- AsymmetricKeyExchangeFormatter.cs
- CodeVariableDeclarationStatement.cs
- CompModSwitches.cs
- WindowsNonControl.cs
- Renderer.cs
- TableRow.cs
- SizeF.cs
- WebPartTracker.cs
- HMAC.cs