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
- SemanticAnalyzer.cs
- ApplyImportsAction.cs
- DBSchemaRow.cs
- LoginView.cs
- Int16Storage.cs
- RawStylusSystemGestureInputReport.cs
- SystemSounds.cs
- DriveNotFoundException.cs
- DateTimeFormat.cs
- AspNetPartialTrustHelpers.cs
- Panel.cs
- StateDesignerConnector.cs
- LineSegment.cs
- ResourceType.cs
- DockProviderWrapper.cs
- ToolStripComboBox.cs
- GestureRecognitionResult.cs
- ExpandSegmentCollection.cs
- DialogBaseForm.cs
- WindowsListView.cs
- WorkflowStateRollbackService.cs
- WebPartUserCapability.cs
- ServiceOperation.cs
- ErrorTolerantObjectWriter.cs
- ToolStripContainerActionList.cs
- CqlQuery.cs
- DebuggerAttributes.cs
- NavigationProgressEventArgs.cs
- Thumb.cs
- SqlClientFactory.cs
- NullableConverter.cs
- Clock.cs
- WindowsBrush.cs
- XamlWriter.cs
- LayoutTable.cs
- NavigatorInput.cs
- GenericRootAutomationPeer.cs
- MD5Cng.cs
- RoleService.cs
- AspNetSynchronizationContext.cs
- WebConfigManager.cs
- ClientType.cs
- BitmapSizeOptions.cs
- UnhandledExceptionEventArgs.cs
- DataPagerField.cs
- TypeInformation.cs
- ComAdminInterfaces.cs
- xmlsaver.cs
- ContentTypeSettingClientMessageFormatter.cs
- BindingNavigator.cs
- GraphicsPath.cs
- RelationshipConverter.cs
- Attributes.cs
- TdsParserStaticMethods.cs
- LambdaCompiler.Lambda.cs
- CollectionAdapters.cs
- entityreference_tresulttype.cs
- TreeViewAutomationPeer.cs
- CodeParameterDeclarationExpression.cs
- NewArrayExpression.cs
- ColumnHeaderConverter.cs
- SspiWrapper.cs
- X509Certificate.cs
- CheckedListBox.cs
- Span.cs
- PageClientProxyGenerator.cs
- HtmlInputCheckBox.cs
- XmlCustomFormatter.cs
- HttpDictionary.cs
- CmsInterop.cs
- ScrollChrome.cs
- PropertyRef.cs
- DataGridColumnHeaderAutomationPeer.cs
- RealProxy.cs
- PageAsyncTaskManager.cs
- XmlIncludeAttribute.cs
- Model3D.cs
- ArglessEventHandlerProxy.cs
- CharacterShapingProperties.cs
- XamlDesignerSerializationManager.cs
- WinEventQueueItem.cs
- ListControlConvertEventArgs.cs
- TreeBuilderXamlTranslator.cs
- CallContext.cs
- PeerCredentialElement.cs
- FileDialogCustomPlace.cs
- Composition.cs
- IncomingWebResponseContext.cs
- DataMemberFieldEditor.cs
- _RequestCacheProtocol.cs
- EntityDataSourceChangingEventArgs.cs
- WebDisplayNameAttribute.cs
- GenericTypeParameterBuilder.cs
- NameTable.cs
- BlurBitmapEffect.cs
- PathGradientBrush.cs
- CharacterMetrics.cs
- DoWhile.cs
- SoapProtocolImporter.cs
- FormsAuthenticationTicket.cs