Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / 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
- Clause.cs
- QilReplaceVisitor.cs
- GenericArgumentsUpdater.cs
- GifBitmapEncoder.cs
- StackOverflowException.cs
- DisableDpiAwarenessAttribute.cs
- Function.cs
- configsystem.cs
- EventSourceCreationData.cs
- XamlParser.cs
- FixedSOMFixedBlock.cs
- DataServiceClientException.cs
- DataRowChangeEvent.cs
- mil_sdk_version.cs
- TypeFieldSchema.cs
- PersonalizableTypeEntry.cs
- UniqueIdentifierService.cs
- UserNameSecurityToken.cs
- ToolStripDropDownClosingEventArgs.cs
- ClientScriptManager.cs
- ListBoxItemWrapperAutomationPeer.cs
- RouteItem.cs
- RoutedEventConverter.cs
- FontUnit.cs
- HttpPostedFile.cs
- SourceSwitch.cs
- DataServiceHost.cs
- ToolStripSettings.cs
- XmlSchemaAnnotation.cs
- MethodToken.cs
- HtmlString.cs
- DynamicActivityProperty.cs
- DoubleLinkList.cs
- PersonalizationDictionary.cs
- ProfileSettings.cs
- QilInvokeEarlyBound.cs
- ObjectCacheHost.cs
- ApplicationDirectoryMembershipCondition.cs
- ObjectListTitleAttribute.cs
- ErrorWebPart.cs
- ObjectAssociationEndMapping.cs
- ConfigXmlCDataSection.cs
- WebPermission.cs
- BitmapEffectInputConnector.cs
- CryptoProvider.cs
- HtmlLink.cs
- DataGridComboBoxColumn.cs
- TableLayoutPanelBehavior.cs
- TextModifier.cs
- ThicknessAnimation.cs
- AsyncPostBackTrigger.cs
- QueryContinueDragEventArgs.cs
- OleDbError.cs
- RecordBuilder.cs
- TimeManager.cs
- XmlMapping.cs
- XomlCompilerError.cs
- OpenTypeLayout.cs
- ZipIOExtraFieldPaddingElement.cs
- DataGridViewAccessibleObject.cs
- ApplicationSecurityManager.cs
- MailBnfHelper.cs
- UpDownEvent.cs
- BamlLocalizer.cs
- UIElement3D.cs
- ThousandthOfEmRealDoubles.cs
- StructuredTypeEmitter.cs
- BuilderPropertyEntry.cs
- SchemaSetCompiler.cs
- ListControl.cs
- _NegoStream.cs
- DataServiceException.cs
- Grant.cs
- CapabilitiesRule.cs
- MailAddressParser.cs
- EmbeddedMailObjectCollectionEditor.cs
- FileSystemEventArgs.cs
- TextElementEnumerator.cs
- ProviderSettings.cs
- RuleSettings.cs
- OrderByBuilder.cs
- EntityModelBuildProvider.cs
- SiteMapNodeCollection.cs
- NameHandler.cs
- CertificateManager.cs
- BaseCollection.cs
- SoapInteropTypes.cs
- HealthMonitoringSectionHelper.cs
- NavigationProperty.cs
- DataGridViewHitTestInfo.cs
- WebPartMenuStyle.cs
- PublishLicense.cs
- DesignTimeHTMLTextWriter.cs
- FunctionDescription.cs
- LeaseManager.cs
- TextParaLineResult.cs
- ManipulationCompletedEventArgs.cs
- ConsoleKeyInfo.cs
- LocalizableResourceBuilder.cs
- ObjectDataSourceStatusEventArgs.cs