Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Base / System / IO / Packaging / CompoundFile / StorageRoot.cs / 1 / StorageRoot.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // The root object for manipulating the WPP container. // // History: // 05/10/2002: [....]: Initial creation. // 06/12/2002: [....]: Catch & translate COMException from native calls. // 06/25/2002: [....]: Add a constructor to build on top of IStorage. // 06/28/2002: [....]: Add a boolean to avoid infinite loops in data space // manager initialization. // 07/31/2002: [....]: Make obvious that we are using security suppressed interfaces. // 05/20/2003: [....]: 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; 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
- FormatConvertedBitmap.cs
- RepeatButtonAutomationPeer.cs
- DispatchWrapper.cs
- Paragraph.cs
- CorrelationScope.cs
- DataGridViewCheckBoxColumn.cs
- Stack.cs
- QueryConverter.cs
- WebPartPersonalization.cs
- Bitmap.cs
- HtmlTableCell.cs
- HebrewNumber.cs
- TypeElementCollection.cs
- AttachedAnnotation.cs
- RepeatButtonAutomationPeer.cs
- FixUpCollection.cs
- ManagementQuery.cs
- TableFieldsEditor.cs
- FamilyCollection.cs
- VisualStyleRenderer.cs
- SrgsRule.cs
- BamlLocalizableResource.cs
- DataKeyArray.cs
- HttpApplication.cs
- SaveWorkflowAsyncResult.cs
- DetailsViewDesigner.cs
- BamlBinaryReader.cs
- GenericUriParser.cs
- HttpValueCollection.cs
- FlowDocumentFormatter.cs
- UnsettableComboBox.cs
- GenerateTemporaryAssemblyTask.cs
- BaseParagraph.cs
- XmlSchemaIdentityConstraint.cs
- Grant.cs
- Help.cs
- ProtocolsSection.cs
- OnOperation.cs
- altserialization.cs
- Logging.cs
- DataViewSettingCollection.cs
- RadioButton.cs
- Visual.cs
- HttpSocketManager.cs
- ToolStripOverflow.cs
- DoubleLinkListEnumerator.cs
- FloaterParaClient.cs
- DynamicQueryableWrapper.cs
- webproxy.cs
- ConfigurationManagerHelperFactory.cs
- BindingManagerDataErrorEventArgs.cs
- WorkflowViewService.cs
- SymbolEqualComparer.cs
- SqlProvider.cs
- StandardBindingCollectionElement.cs
- XPathScanner.cs
- IApplicationTrustManager.cs
- SqlUserDefinedAggregateAttribute.cs
- XmlCollation.cs
- StringDictionaryCodeDomSerializer.cs
- Serializer.cs
- OracleBinary.cs
- METAHEADER.cs
- MetadataArtifactLoaderCompositeResource.cs
- AnimationLayer.cs
- ProviderException.cs
- DeflateEmulationStream.cs
- TraceFilter.cs
- CryptoApi.cs
- SiteMapDataSource.cs
- Lasso.cs
- InputQueue.cs
- DrawingAttributesDefaultValueFactory.cs
- ListDictionaryInternal.cs
- FirstMatchCodeGroup.cs
- StorageEntitySetMapping.cs
- Expressions.cs
- Pen.cs
- MsmqInputMessage.cs
- UiaCoreTypesApi.cs
- WindowsIPAddress.cs
- Mouse.cs
- CombinedGeometry.cs
- ToolBarOverflowPanel.cs
- RandomNumberGenerator.cs
- LinearKeyFrames.cs
- ExtractorMetadata.cs
- TypeToken.cs
- DbReferenceCollection.cs
- ConnectionPointCookie.cs
- RefreshPropertiesAttribute.cs
- ValidationException.cs
- MobileListItem.cs
- DataConnectionHelper.cs
- LogExtent.cs
- WebEvents.cs
- XamlPoint3DCollectionSerializer.cs
- LinkedList.cs
- _HTTPDateParse.cs
- DataContractSerializerOperationBehavior.cs