Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / IO / Packaging / unsafeIndexingFilterStream.cs / 1 / unsafeIndexingFilterStream.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2005 // // File: UnsafeIndexingFilterStream.cs // // Description: The class UnsafeIndexingFilterStream uses an OLE IStream component // passed on a indexing filter's IPersistStream interface to implement // the System.IO.Stream functions necessary for filtering a document. // In other words, it basically implements a seekable read-only stream. // // For a more complete example of an IStream adapter, see Listing 20.2 // in Adam Nathan's ".Net and COM". // // History: 02/15/05 - johnlarc - initial implementation //----------------------------------------------------------------------------- using System; using System.IO; using System.Runtime.InteropServices; // For Marshal using System.Windows; // for ExceptionStringTable using MS.Win32; // For NativeMethods using MS.Internal.Interop; // for IStream using System.Security; // For SecurityCritical namespace MS.Internal.IO.Packaging { ////// The class UnsafeIndexingFilterStream uses an OLE IStream component /// passed on an indexing filter's IPersistStream interface to implement /// the System.IO.Stream functions necessary for filtering a document. /// In other words, it basically implements a seekable read-only stream. /// ////// /// This class is used only by the Container filter, since the Xaml filter is not accessible directly /// from unmanaged code and so can use System.IO.Stream natively. /// /// This class does not own the process of closing the underlying stream. However, /// This class does own a reference to a COM object that should be released as a part of the Dispose pattern, /// so that the underlying unmanaged code doesn't keep the stream open indefinitely (or until GC gets to it) /// /// The definition of IStream that is used is MS.Internal.Interop.IStream rather than the standard one /// so as to allow efficient marshaling of arrays with specified offsets in Read. /// ////// Critical: Marking this as Security Critical as this stream serves a very specific functionality /// required for indexing content using unmanaged Indexing Services. We do not want managed /// code to start using this Stream implementation. /// This code is meant to be accessed only from unmanaged code. Currently there is one /// unmanaged caller. /// This stream- 1. Calls into unmanaged code. /// 2. Implements a seekable read-only stream on an OLE IStream component. /// 3. Behaves more like an unmanaged IStream as opposed to managed Stream. /// 4. This class does not do any elevation of privilege. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal class UnsafeIndexingFilterStream : Stream { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- ////// Build a System.IO.Stream implementation around an IStream component. /// ////// The client code is entirely responsible for the lifespan of the stream, /// and there is no way it can tip us off for when to release it. Therefore, /// its reference count is not incremented. The risk of the client /// releasing the IStream component before we're done with it is no worse than /// that of the client passing a pointer to garbage in the first place, and we /// cannot protect against that either. After all, the client is unmanaged and /// has endless possibilities of trashing the machine if she wishes to. /// internal UnsafeIndexingFilterStream(IStream oleStream) { if (oleStream == null) throw new ArgumentNullException("oleStream"); _oleStream = oleStream; _disposed = false; } //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- ////// Return the bytes requested. /// /// Destination buffer. /// The zero-based byte offset in buffer at which to begin storing the data read from the current stream. /// How many bytes requested. ///How many bytes were written into buffer. public unsafe override int Read(byte[] buffer, int offset, int count) { ThrowIfStreamDisposed(); // Check arguments. PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count); // Reading 0 bytes is a no-op. if (count == 0) return 0; // Prepare location of return value and call the COM object. int bytesRead; IntPtr pBytesRead = new IntPtr(&bytesRead); // Prepare to restore position in case the read fails. long positionBeforeReadAttempt = this.Position; try { // Pin the array wrt GC while using an address in it. fixed (byte *bufferPointer = &buffer[offset]) { _oleStream.Read(new IntPtr(bufferPointer), count, pBytesRead); } } catch (COMException comException) { this.Position = positionBeforeReadAttempt; throw new IOException("Read", comException); } catch (IOException ioException) { this.Position = positionBeforeReadAttempt; throw new IOException("Read", ioException); } return bytesRead; } ////// Seek -unmanaged streams do not allow seeking beyond the end of the stream /// and since we rely on the underlying stream to validate and return the seek /// results, unlike managed streams where seeking beyond the end of the stream /// is allowed we will get an exception. /// /// Offset in byte. /// Offset origin (start, current, or end). public unsafe override long Seek(long offset, SeekOrigin origin) { ThrowIfStreamDisposed(); long position = 0; // The address of 'position' can be used without pinning the object, because it // is a value and is therefore allocated on the stack rather than the heap. IntPtr positionAddress = new IntPtr(&position); // The enum values of SeekOrigin match the STREAM_SEEK_* values. This // convention is as good as carved in stone, so there's no need for a switch here. _oleStream.Seek(offset, (int)origin, positionAddress); return position; } ////// SetLength /// ///not supported ////// Not supported. No indexing filter should require it. /// public override void SetLength(long newLength) { ThrowIfStreamDisposed(); throw new NotSupportedException(SR.Get(SRID.StreamDoesNotSupportWrite)); } ////// Write /// ///not supported ////// Not supported. No indexing filter should require it. /// public override void Write(byte[] buf, int offset, int count) { ThrowIfStreamDisposed(); throw new NotSupportedException(SR.Get(SRID.StreamDoesNotSupportWrite)); } ////// Flush /// public override void Flush() { ThrowIfStreamDisposed(); //This stream is always readonly, and calling this method is a no-op //No IndexingFilter should require this method. } //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ ////// Is stream readable? /// ////// We always return true, because there's no way of checking whether the caller /// has closed the stream. /// public override bool CanRead { get { return !_disposed; } } ////// Is stream seekable? /// public override bool CanSeek { get { // This information is not available from the underlying stream. // So one assumption has to be made. True is the most common for indexable streams. return !_disposed; } } ////// Is stream writable? /// public override bool CanWrite { get { return false; } } ////// Logical byte position in this stream /// public override long Position { get { ThrowIfStreamDisposed(); return Seek(0, SeekOrigin.Current); } set { ThrowIfStreamDisposed(); if (value < 0) throw new ArgumentException(SR.Get(SRID.CannotSetNegativePosition)); Seek(value, SeekOrigin.Begin); } } ////// Length. /// public override long Length { get { ThrowIfStreamDisposed(); // Retrieve stream stats. STATFLAG_NONAME means don't return the stream name. System.Runtime.InteropServices.ComTypes.STATSTG statstg; _oleStream.Stat(out statstg, NativeMethods.STATFLAG_NONAME); return statstg.cbSize; } } //----------------------------------------------------- // // Protected methods. // //------------------------------------------------------ ////// protected override void Dispose(bool disposing) { try { if (disposing) { if (_oleStream != null) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject(_oleStream); } } } finally { // Calls to Dispose(bool) are expected to bubble up through the class hierarchy. _oleStream = null; _disposed = true; base.Dispose(disposing); } } //----------------------------------------------------- // // Private methods. // //----------------------------------------------------- private void ThrowIfStreamDisposed() { if (_disposed) throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); } //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ private IStream _oleStream; // Underlying COM component. private bool _disposed; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2005 // // File: UnsafeIndexingFilterStream.cs // // Description: The class UnsafeIndexingFilterStream uses an OLE IStream component // passed on a indexing filter's IPersistStream interface to implement // the System.IO.Stream functions necessary for filtering a document. // In other words, it basically implements a seekable read-only stream. // // For a more complete example of an IStream adapter, see Listing 20.2 // in Adam Nathan's ".Net and COM". // // History: 02/15/05 - johnlarc - initial implementation //----------------------------------------------------------------------------- using System; using System.IO; using System.Runtime.InteropServices; // For Marshal using System.Windows; // for ExceptionStringTable using MS.Win32; // For NativeMethods using MS.Internal.Interop; // for IStream using System.Security; // For SecurityCritical namespace MS.Internal.IO.Packaging { ////// Although UnsafeIndexingFilterStream does not close the underlying stream, it is responsible for releasing /// the ComObject it holds, so that unmanaged code can properly close the stream. /// /// This method gets invoked as part of the base class's Dispose() or Close() implementation. /// ////// The class UnsafeIndexingFilterStream uses an OLE IStream component /// passed on an indexing filter's IPersistStream interface to implement /// the System.IO.Stream functions necessary for filtering a document. /// In other words, it basically implements a seekable read-only stream. /// ////// /// This class is used only by the Container filter, since the Xaml filter is not accessible directly /// from unmanaged code and so can use System.IO.Stream natively. /// /// This class does not own the process of closing the underlying stream. However, /// This class does own a reference to a COM object that should be released as a part of the Dispose pattern, /// so that the underlying unmanaged code doesn't keep the stream open indefinitely (or until GC gets to it) /// /// The definition of IStream that is used is MS.Internal.Interop.IStream rather than the standard one /// so as to allow efficient marshaling of arrays with specified offsets in Read. /// ////// Critical: Marking this as Security Critical as this stream serves a very specific functionality /// required for indexing content using unmanaged Indexing Services. We do not want managed /// code to start using this Stream implementation. /// This code is meant to be accessed only from unmanaged code. Currently there is one /// unmanaged caller. /// This stream- 1. Calls into unmanaged code. /// 2. Implements a seekable read-only stream on an OLE IStream component. /// 3. Behaves more like an unmanaged IStream as opposed to managed Stream. /// 4. This class does not do any elevation of privilege. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal class UnsafeIndexingFilterStream : Stream { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- ////// Build a System.IO.Stream implementation around an IStream component. /// ////// The client code is entirely responsible for the lifespan of the stream, /// and there is no way it can tip us off for when to release it. Therefore, /// its reference count is not incremented. The risk of the client /// releasing the IStream component before we're done with it is no worse than /// that of the client passing a pointer to garbage in the first place, and we /// cannot protect against that either. After all, the client is unmanaged and /// has endless possibilities of trashing the machine if she wishes to. /// internal UnsafeIndexingFilterStream(IStream oleStream) { if (oleStream == null) throw new ArgumentNullException("oleStream"); _oleStream = oleStream; _disposed = false; } //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- ////// Return the bytes requested. /// /// Destination buffer. /// The zero-based byte offset in buffer at which to begin storing the data read from the current stream. /// How many bytes requested. ///How many bytes were written into buffer. public unsafe override int Read(byte[] buffer, int offset, int count) { ThrowIfStreamDisposed(); // Check arguments. PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count); // Reading 0 bytes is a no-op. if (count == 0) return 0; // Prepare location of return value and call the COM object. int bytesRead; IntPtr pBytesRead = new IntPtr(&bytesRead); // Prepare to restore position in case the read fails. long positionBeforeReadAttempt = this.Position; try { // Pin the array wrt GC while using an address in it. fixed (byte *bufferPointer = &buffer[offset]) { _oleStream.Read(new IntPtr(bufferPointer), count, pBytesRead); } } catch (COMException comException) { this.Position = positionBeforeReadAttempt; throw new IOException("Read", comException); } catch (IOException ioException) { this.Position = positionBeforeReadAttempt; throw new IOException("Read", ioException); } return bytesRead; } ////// Seek -unmanaged streams do not allow seeking beyond the end of the stream /// and since we rely on the underlying stream to validate and return the seek /// results, unlike managed streams where seeking beyond the end of the stream /// is allowed we will get an exception. /// /// Offset in byte. /// Offset origin (start, current, or end). public unsafe override long Seek(long offset, SeekOrigin origin) { ThrowIfStreamDisposed(); long position = 0; // The address of 'position' can be used without pinning the object, because it // is a value and is therefore allocated on the stack rather than the heap. IntPtr positionAddress = new IntPtr(&position); // The enum values of SeekOrigin match the STREAM_SEEK_* values. This // convention is as good as carved in stone, so there's no need for a switch here. _oleStream.Seek(offset, (int)origin, positionAddress); return position; } ////// SetLength /// ///not supported ////// Not supported. No indexing filter should require it. /// public override void SetLength(long newLength) { ThrowIfStreamDisposed(); throw new NotSupportedException(SR.Get(SRID.StreamDoesNotSupportWrite)); } ////// Write /// ///not supported ////// Not supported. No indexing filter should require it. /// public override void Write(byte[] buf, int offset, int count) { ThrowIfStreamDisposed(); throw new NotSupportedException(SR.Get(SRID.StreamDoesNotSupportWrite)); } ////// Flush /// public override void Flush() { ThrowIfStreamDisposed(); //This stream is always readonly, and calling this method is a no-op //No IndexingFilter should require this method. } //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ ////// Is stream readable? /// ////// We always return true, because there's no way of checking whether the caller /// has closed the stream. /// public override bool CanRead { get { return !_disposed; } } ////// Is stream seekable? /// public override bool CanSeek { get { // This information is not available from the underlying stream. // So one assumption has to be made. True is the most common for indexable streams. return !_disposed; } } ////// Is stream writable? /// public override bool CanWrite { get { return false; } } ////// Logical byte position in this stream /// public override long Position { get { ThrowIfStreamDisposed(); return Seek(0, SeekOrigin.Current); } set { ThrowIfStreamDisposed(); if (value < 0) throw new ArgumentException(SR.Get(SRID.CannotSetNegativePosition)); Seek(value, SeekOrigin.Begin); } } ////// Length. /// public override long Length { get { ThrowIfStreamDisposed(); // Retrieve stream stats. STATFLAG_NONAME means don't return the stream name. System.Runtime.InteropServices.ComTypes.STATSTG statstg; _oleStream.Stat(out statstg, NativeMethods.STATFLAG_NONAME); return statstg.cbSize; } } //----------------------------------------------------- // // Protected methods. // //------------------------------------------------------ ////// protected override void Dispose(bool disposing) { try { if (disposing) { if (_oleStream != null) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject(_oleStream); } } } finally { // Calls to Dispose(bool) are expected to bubble up through the class hierarchy. _oleStream = null; _disposed = true; base.Dispose(disposing); } } //----------------------------------------------------- // // Private methods. // //----------------------------------------------------- private void ThrowIfStreamDisposed() { if (_disposed) throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed)); } //----------------------------------------------------- // // Private Fields // //------------------------------------------------------ private IStream _oleStream; // Underlying COM component. private bool _disposed; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved./// Although UnsafeIndexingFilterStream does not close the underlying stream, it is responsible for releasing /// the ComObject it holds, so that unmanaged code can properly close the stream. /// /// This method gets invoked as part of the base class's Dispose() or Close() implementation. /// ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RequestCachePolicy.cs
- TemplateControl.cs
- MappingMetadataHelper.cs
- Html32TextWriter.cs
- MenuItemStyleCollection.cs
- BuilderElements.cs
- MapPathBasedVirtualPathProvider.cs
- Variable.cs
- MenuItemBindingCollection.cs
- DataServiceHostFactory.cs
- ConnectionStringSettings.cs
- GZipStream.cs
- CmsInterop.cs
- SafeProcessHandle.cs
- GroupItem.cs
- counter.cs
- SafeEventLogWriteHandle.cs
- PathFigureCollection.cs
- SymDocumentType.cs
- HexParser.cs
- XmlText.cs
- AppSettingsReader.cs
- SimpleApplicationHost.cs
- UnlockCardRequest.cs
- ShortcutKeysEditor.cs
- TransportConfigurationTypeElementCollection.cs
- ItemsPresenter.cs
- PointLightBase.cs
- Models.cs
- CaseCqlBlock.cs
- XPathBinder.cs
- externdll.cs
- VariableQuery.cs
- DataGridViewComboBoxCell.cs
- OLEDB_Enum.cs
- SqlTrackingQuery.cs
- RadioButtonDesigner.cs
- WCFBuildProvider.cs
- HtmlDocument.cs
- RemoteWebConfigurationHostStream.cs
- DataGridViewRow.cs
- TranslateTransform.cs
- LingerOption.cs
- QilPatternVisitor.cs
- AccessViolationException.cs
- EventProperty.cs
- SecurityPermission.cs
- AffineTransform3D.cs
- MSAAEventDispatcher.cs
- GenericXmlSecurityToken.cs
- UnsafeNativeMethods.cs
- DynamicQueryStringParameter.cs
- PageAdapter.cs
- DataGridHeaderBorder.cs
- CurrentChangingEventManager.cs
- KoreanLunisolarCalendar.cs
- TcpTransportSecurityElement.cs
- arclist.cs
- Version.cs
- VScrollProperties.cs
- DataSourceSelectArguments.cs
- SrgsGrammarCompiler.cs
- Line.cs
- PerspectiveCamera.cs
- Types.cs
- AspNetSynchronizationContext.cs
- DbParameterHelper.cs
- SourceElementsCollection.cs
- SchemaCollectionPreprocessor.cs
- SQlBooleanStorage.cs
- DataTableReaderListener.cs
- IdentityReference.cs
- ReferenceService.cs
- RemotingServices.cs
- WinCategoryAttribute.cs
- MenuEventArgs.cs
- ResourceContainerWrapper.cs
- PrtCap_Public_Simple.cs
- JavaScriptString.cs
- CodePageUtils.cs
- OdbcFactory.cs
- WindowsToolbarAsMenu.cs
- DataGridViewCellParsingEventArgs.cs
- WmiEventSink.cs
- CLSCompliantAttribute.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- XmlSchemaIdentityConstraint.cs
- StreamReader.cs
- Selection.cs
- SurrogateSelector.cs
- FindCriteria11.cs
- RightNameExpirationInfoPair.cs
- OrderedDictionary.cs
- ProfileProvider.cs
- ForwardPositionQuery.cs
- EdmError.cs
- ContextQuery.cs
- EmptyReadOnlyDictionaryInternal.cs
- ColumnHeaderConverter.cs
- DocumentGridContextMenu.cs