Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / 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 - [....] - 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./// 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
- ToolStripMenuItem.cs
- StringConverter.cs
- SmiTypedGetterSetter.cs
- XmlSchemaSimpleContent.cs
- SqlClientFactory.cs
- VersionedStreamOwner.cs
- ConstructorBuilder.cs
- StrongNameKeyPair.cs
- EntitySetBaseCollection.cs
- UserPreferenceChangingEventArgs.cs
- StringDictionaryEditor.cs
- DefinitionProperties.cs
- SqlTypesSchemaImporter.cs
- XmlSchemaDatatype.cs
- SecurityResources.cs
- XmlName.cs
- WindowsFormsLinkLabel.cs
- TypedTableBaseExtensions.cs
- MLangCodePageEncoding.cs
- EntityProviderServices.cs
- Rights.cs
- CodeLinePragma.cs
- HostedElements.cs
- WeakKeyDictionary.cs
- OpCodes.cs
- FloaterParaClient.cs
- EventLogPermission.cs
- SQLDecimalStorage.cs
- MailFileEditor.cs
- RegexMatch.cs
- ReversePositionQuery.cs
- HybridDictionary.cs
- MemoryRecordBuffer.cs
- WebHttpElement.cs
- CodeNamespaceImportCollection.cs
- TextServicesCompartmentContext.cs
- TablePattern.cs
- ClientSponsor.cs
- ListItemParagraph.cs
- OdbcHandle.cs
- SpAudioStreamWrapper.cs
- WrappedReader.cs
- _DomainName.cs
- SimpleRecyclingCache.cs
- ConstantCheck.cs
- AutoGeneratedFieldProperties.cs
- WebServiceClientProxyGenerator.cs
- SrgsRuleRef.cs
- VisualStyleElement.cs
- AuthenticationModuleElementCollection.cs
- ConnectionStringsExpressionBuilder.cs
- DrawingContextDrawingContextWalker.cs
- ConfigurationPermission.cs
- ResourceAssociationSet.cs
- ResXResourceWriter.cs
- PointCollectionConverter.cs
- SRDisplayNameAttribute.cs
- ProfileBuildProvider.cs
- ProfileSection.cs
- HopperCache.cs
- WrappingXamlSchemaContext.cs
- TextBox.cs
- WebPartUserCapability.cs
- DeploymentExceptionMapper.cs
- TextElementEnumerator.cs
- ValueTypeFixupInfo.cs
- SerialStream.cs
- LinqMaximalSubtreeNominator.cs
- WebHttpBinding.cs
- ArgumentsParser.cs
- CodeDirectionExpression.cs
- ListMarkerSourceInfo.cs
- KeyNotFoundException.cs
- CharacterBufferReference.cs
- ExtractedStateEntry.cs
- Point3DCollectionConverter.cs
- WebAdminConfigurationHelper.cs
- DoubleLinkList.cs
- odbcmetadatafactory.cs
- ThreadAttributes.cs
- NetDataContractSerializer.cs
- PasswordTextNavigator.cs
- XmlReflectionMember.cs
- PartialCachingControl.cs
- AccessKeyManager.cs
- DataGridDesigner.cs
- TableCell.cs
- PropertyGroupDescription.cs
- DbException.cs
- ParserHooks.cs
- safesecurityhelperavalon.cs
- DataControlFieldHeaderCell.cs
- WebCategoryAttribute.cs
- PageThemeParser.cs
- PageCache.cs
- DesignerSerializerAttribute.cs
- EndpointDesigner.cs
- SoapObjectReader.cs
- Point.cs
- LOSFormatter.cs