Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Media / StreamAsIStream.cs / 1 / StreamAsIStream.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2002-2003 // // File: StreamAsIStream.cs //----------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages using System.Windows.Media; using System.Security; using System.Security.Permissions; using System; using MS.Internal; using MS.Win32; using System.Reflection; using System.Collections; using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Internal; using MS.Internal.PresentationCore; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods; // TODOTODO Make our own namespace for internal stuff. namespace System.Windows.Media { #region StreamDescriptor [StructLayout(LayoutKind.Sequential)] internal struct StreamDescriptor { internal delegate void Dispose(ref StreamDescriptor pSD); internal delegate int Read(ref StreamDescriptor pSD, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out]byte[] buffer, uint cb, out uint cbRead); internal unsafe delegate int Seek(ref StreamDescriptor pSD, long offset, uint origin, long* plibNewPostion); internal delegate int Stat(ref StreamDescriptor pSD, out System.Runtime.InteropServices.ComTypes.STATSTG statstg, uint grfStatFlag); internal delegate int Write(ref StreamDescriptor pSD, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]byte[] buffer, uint cb, out uint cbWritten); internal delegate int CopyTo(ref StreamDescriptor pSD, IntPtr pstm, long cb, out long cbRead, out long cbWritten); internal delegate int SetSize(ref StreamDescriptor pSD, long value); internal delegate int Revert(ref StreamDescriptor pSD); internal delegate int Commit(ref StreamDescriptor pSD, UInt32 grfCommitFlags); internal delegate int LockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType); internal delegate int UnlockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType); internal delegate int Clone(ref StreamDescriptor pSD, out IntPtr stream); internal delegate int CanWrite(ref StreamDescriptor pSD, out bool canWrite); internal delegate int CanSeek(ref StreamDescriptor pSD, out bool canSeek); internal Dispose pfnDispose; internal Read pfnRead; internal Seek pfnSeek; internal Stat pfnStat; internal Write pfnWrite; internal CopyTo pfnCopyTo; internal SetSize pfnSetSize; internal Commit pfnCommit; internal Revert pfnRevert; internal LockRegion pfnLockRegion; internal UnlockRegion pfnUnlockRegion; internal Clone pfnClone; internal CanWrite pfnCanWrite; internal CanSeek pfnCanSeek; ////// Critical: This code calls into link demand protected GCHandle /// TreatAsSafe: This code is ok to expose especially since it does not expose the handle /// [SecurityCritical, SecurityTreatAsSafe] internal static void StaticDispose(ref StreamDescriptor pSD) { Debug.Assert(((IntPtr)pSD.m_handle) != IntPtr.Zero, "If this asserts fires: why is it firing. It might be legal in future."); StreamAsIStream sais = (StreamAsIStream)(pSD.m_handle.Target); ((System.Runtime.InteropServices.GCHandle)(pSD.m_handle)).Free(); } internal System.Runtime.InteropServices.GCHandle m_handle; } #endregion #region StaticPtrs ////// We need to keep the delegates alive. /// internal static class StaticPtrs { ////// Critical - this method has an unsafe block and references StreamAsIStream.Seek /// TreatAsSafe - referenced function pointer is well known /// [SecurityCritical, SecurityTreatAsSafe] static StaticPtrs() { StaticPtrs.pfnDispose = new StreamDescriptor.Dispose(StreamDescriptor.StaticDispose); StaticPtrs.pfnClone = new StreamDescriptor.Clone(StreamAsIStream.Clone); StaticPtrs.pfnCommit = new StreamDescriptor.Commit(StreamAsIStream.Commit); StaticPtrs.pfnCopyTo = new StreamDescriptor.CopyTo(StreamAsIStream.CopyTo); StaticPtrs.pfnLockRegion = new StreamDescriptor.LockRegion(StreamAsIStream.LockRegion); StaticPtrs.pfnRead = new StreamDescriptor.Read(StreamAsIStream.Read); StaticPtrs.pfnRevert = new StreamDescriptor.Revert(StreamAsIStream.Revert); unsafe { StaticPtrs.pfnSeek = new StreamDescriptor.Seek(StreamAsIStream.Seek); } StaticPtrs.pfnSetSize = new StreamDescriptor.SetSize(StreamAsIStream.SetSize); StaticPtrs.pfnStat = new StreamDescriptor.Stat(StreamAsIStream.Stat); StaticPtrs.pfnUnlockRegion = new StreamDescriptor.UnlockRegion(StreamAsIStream.UnlockRegion); StaticPtrs.pfnWrite = new StreamDescriptor.Write(StreamAsIStream.Write); StaticPtrs.pfnCanWrite = new StreamDescriptor.CanWrite(StreamAsIStream.CanWrite); StaticPtrs.pfnCanSeek = new StreamDescriptor.CanSeek(StreamAsIStream.CanSeek); } internal static StreamDescriptor.Dispose pfnDispose; internal static StreamDescriptor.Read pfnRead; internal static StreamDescriptor.Seek pfnSeek; internal static StreamDescriptor.Stat pfnStat; internal static StreamDescriptor.Write pfnWrite; internal static StreamDescriptor.CopyTo pfnCopyTo; internal static StreamDescriptor.SetSize pfnSetSize; internal static StreamDescriptor.Commit pfnCommit; internal static StreamDescriptor.Revert pfnRevert; internal static StreamDescriptor.LockRegion pfnLockRegion; internal static StreamDescriptor.UnlockRegion pfnUnlockRegion; internal static StreamDescriptor.Clone pfnClone; internal static StreamDescriptor.CanWrite pfnCanWrite; internal static StreamDescriptor.CanSeek pfnCanSeek; } #endregion #region StreamAsIStream //CASRemoval:[System.Security.SuppressUnmanagedCodeSecurity] internal class StreamAsIStream { #region Instance Data const int STREAM_SEEK_SET = 0x0; const int STREAM_SEEK_CUR = 0x1; const int STREAM_SEEK_END = 0x2; protected System.IO.Stream dataStream; private Exception _lastException; // to support seeking ahead of the stream length... private long virtualPosition = -1; #endregion #region Constructor private StreamAsIStream(System.IO.Stream dataStream) { this.dataStream = dataStream; } #endregion #region Private Methods private void ActualizeVirtualPosition() { if (virtualPosition == -1) { return; } if (virtualPosition > dataStream.Length) { dataStream.SetLength(virtualPosition); } dataStream.Position = virtualPosition; virtualPosition = -1; } #endregion #region StreamFunctions public int Clone(out IntPtr stream) { stream = IntPtr.Zero; #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } public int Commit(uint grfCommitFlags) { #pragma warning disable 6500 try { Verify(); dataStream.Flush(); // Extend the length of the file if needed. ActualizeVirtualPosition(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int CopyTo(IntPtr /* IStream */ pstm, long cb, out long cbRead, out long cbWritten) { int hr = NativeMethods.S_OK; uint bufsize = 4096; // one page byte[] buffer = new byte[bufsize]; cbWritten = 0; cbRead = 0; #pragma warning disable 6500 try { Verify(); while (cbWritten < cb) { uint toRead = bufsize; if (cbWritten + toRead > cb) { toRead = (uint) (cb - cbWritten); } uint read = 0; hr = Read(buffer, toRead, out read); if (read == 0) { break; } cbRead += read; uint written = 0; hr = MILIStreamWrite(pstm, buffer, read, out written); if (written != read) { return hr; } cbWritten += read; } } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return hr; } public int LockRegion(long libOffset, long cb, uint dwLockType) { #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } public int Read(byte[] buffer, uint cb, out uint cbRead) { cbRead = 0; #pragma warning disable 6500 try { Verify(); ActualizeVirtualPosition(); cbRead = (uint) dataStream.Read(buffer, 0, (int) cb); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int Revert() { #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } ////// Critical - this method is unsafe - it cannot warrant the validity of the given pointer /// [SecurityCritical] public unsafe int Seek(long offset, uint origin, long * plibNewPostion) { #pragma warning disable 6500 try { Verify(); long pos = virtualPosition; if (virtualPosition == -1) { pos = dataStream.Position; } long len = dataStream.Length; switch (origin) { case STREAM_SEEK_SET: if (offset <= len) { dataStream.Position = offset; virtualPosition = -1; } else { virtualPosition = offset; } break; case STREAM_SEEK_END: if (offset <= 0) { dataStream.Position = len + offset; virtualPosition = -1; } else { virtualPosition = len + offset; } break; case STREAM_SEEK_CUR: if (offset+pos <= len) { dataStream.Position = pos + offset; virtualPosition = -1; } else { virtualPosition = offset + pos; } break; } if (plibNewPostion!=null) { if (virtualPosition != -1) { *plibNewPostion = virtualPosition; } else { *plibNewPostion = dataStream.Position; } } } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int SetSize(long value) { #pragma warning disable 6500 try { Verify(); dataStream.SetLength(value); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int Stat(out System.Runtime.InteropServices.ComTypes.STATSTG statstg, uint grfStatFlag) { System.Runtime.InteropServices.ComTypes.STATSTG statstgOut = new System.Runtime.InteropServices.ComTypes.STATSTG(); statstg = statstgOut; #pragma warning disable 6500 try { Verify(); statstgOut.type = 2; // STGTY_STREAM statstgOut.cbSize = dataStream.Length; statstgOut.grfLocksSupported = 2; //LOCK_EXCLUSIVE statstgOut.pwcsName = null; statstg = statstgOut; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int UnlockRegion(long libOffset, long cb, uint dwLockType) { #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } public int Write(byte[] buffer, uint cb, out uint cbWritten) { cbWritten = 0; #pragma warning disable 6500 try { Verify(); ActualizeVirtualPosition(); dataStream.Write(buffer, 0, (int) cb); cbWritten = cb; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int CanWrite(out bool canWrite) { canWrite = false; #pragma warning disable 6500 try { Verify(); canWrite = dataStream.CanWrite; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int CanSeek(out bool canSeek) { canSeek = false; #pragma warning disable 6500 try { Verify(); canSeek = dataStream.CanSeek; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } #endregion #region Verify private void Verify() { if (this.dataStream == null) { throw new System.ObjectDisposedException(SR.Get(SRID.Media_StreamClosed)); } } #endregion #region Delegate Implemetations ////// Critical: This code calls into link demand protected GCHandle /// TreatAsSafe: This code is ok to expose /// [SecurityCritical,SecurityTreatAsSafe] internal static StreamAsIStream FromSD(ref StreamDescriptor sd) { Debug.Assert(((IntPtr)sd.m_handle) != IntPtr.Zero, "Stream is disposed."); System.Runtime.InteropServices.GCHandle handle = (System.Runtime.InteropServices.GCHandle)(sd.m_handle); return (StreamAsIStream)(handle.Target); } internal static int Clone(ref StreamDescriptor pSD, out IntPtr stream) { return (StreamAsIStream.FromSD(ref pSD)).Clone(out stream); } internal static int Commit(ref StreamDescriptor pSD, UInt32 grfCommitFlags) { return (StreamAsIStream.FromSD(ref pSD)).Commit(grfCommitFlags); } internal static int CopyTo(ref StreamDescriptor pSD, IntPtr pstm, long cb, out long cbRead, out long cbWritten) { return (StreamAsIStream.FromSD(ref pSD)).CopyTo(pstm, cb, out cbRead, out cbWritten); } internal static int LockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType) { return (StreamAsIStream.FromSD(ref pSD)).LockRegion(libOffset, cb, dwLockType); } internal static int Read(ref StreamDescriptor pSD, byte[] buffer, uint cb, out uint cbRead) { return (StreamAsIStream.FromSD(ref pSD)).Read(buffer, cb, out cbRead); } internal static int Revert(ref StreamDescriptor pSD) { return (StreamAsIStream.FromSD(ref pSD)).Revert(); } ////// Critical - this method is unsafe - it cannot warrant the validity of the given pointer /// [SecurityCritical] internal unsafe static int Seek(ref StreamDescriptor pSD, long offset, uint origin, long* plibNewPostion) { return (StreamAsIStream.FromSD(ref pSD)).Seek(offset, origin, plibNewPostion); } internal static int SetSize(ref StreamDescriptor pSD, long value) { return (StreamAsIStream.FromSD(ref pSD)).SetSize(value); } internal static int Stat(ref StreamDescriptor pSD, out System.Runtime.InteropServices.ComTypes.STATSTG statstg, uint grfStatFlag) { return (StreamAsIStream.FromSD(ref pSD)).Stat(out statstg, grfStatFlag); } internal static int UnlockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType) { return (StreamAsIStream.FromSD(ref pSD)).UnlockRegion(libOffset, cb, dwLockType); } internal static int Write(ref StreamDescriptor pSD, byte[] buffer, uint cb, out uint cbWritten) { return (StreamAsIStream.FromSD(ref pSD)).Write(buffer, cb, out cbWritten); } internal static int CanWrite(ref StreamDescriptor pSD, out bool canWrite) { return (StreamAsIStream.FromSD(ref pSD)).CanWrite(out canWrite); } internal static int CanSeek(ref StreamDescriptor pSD, out bool canSeek) { return (StreamAsIStream.FromSD(ref pSD)).CanSeek(out canSeek); } #endregion // Takes an IStream that is potentially not seekable and returns // a seekable memory stream that is a copy of it. ////// Critical - calls unmanaged code, takes unmanaged pointer argument /// [SecurityCritical] internal static IntPtr IStreamMemoryFrom(IntPtr comStream) { IntPtr pIStream = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { if (HRESULT.Failed(UnsafeNativeMethods.WICImagingFactory.CreateStream(myFactory.ImagingFactoryPtr, out pIStream))) { return IntPtr.Zero; } if (HRESULT.Failed(UnsafeNativeMethods.WICStream.InitializeFromIStream(pIStream, comStream))) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pIStream); return IntPtr.Zero; } } return pIStream; } ////// Critical - calls unmanaged code, accepts unmanaged pointers /// [SecurityCritical] internal static IntPtr IStreamFrom(IntPtr memoryBuffer, int bufferSize) { IntPtr pIStream = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { if (HRESULT.Failed(UnsafeNativeMethods.WICImagingFactory.CreateStream(myFactory.ImagingFactoryPtr, out pIStream))) { return IntPtr.Zero; } if (HRESULT.Failed(UnsafeNativeMethods.WICStream.InitializeFromMemory(pIStream, memoryBuffer, (uint) bufferSize))) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pIStream); return IntPtr.Zero; } } return pIStream; } #region IStreamFrom System.IO.Stream ////// Critical - calls critical code, create unmanaged structures /// [SecurityCritical] internal static IntPtr IStreamFrom(System.IO.Stream stream) { if (stream == null) { throw new System.ArgumentNullException("stream"); } IntPtr pStream = IntPtr.Zero; StreamAsIStream sais = new StreamAsIStream(stream); StreamDescriptor sd = new StreamDescriptor(); sd.pfnDispose = StaticPtrs.pfnDispose; sd.pfnClone = StaticPtrs.pfnClone; sd.pfnCommit = StaticPtrs.pfnCommit; sd.pfnCopyTo = StaticPtrs.pfnCopyTo; sd.pfnLockRegion = StaticPtrs.pfnLockRegion; sd.pfnRead = StaticPtrs.pfnRead; sd.pfnRevert = StaticPtrs.pfnRevert; unsafe { sd.pfnSeek = StaticPtrs.pfnSeek; } sd.pfnSetSize = StaticPtrs.pfnSetSize; sd.pfnStat = StaticPtrs.pfnStat; sd.pfnUnlockRegion = StaticPtrs.pfnUnlockRegion; sd.pfnWrite = StaticPtrs.pfnWrite; sd.pfnCanWrite = StaticPtrs.pfnCanWrite; sd.pfnCanSeek = StaticPtrs.pfnCanSeek; sd.m_handle = System.Runtime.InteropServices.GCHandle.Alloc(sais, System.Runtime.InteropServices.GCHandleType.Normal); HRESULT.Check(UnsafeNativeMethods.MilCoreApi.MILCreateStreamFromStreamDescriptor(ref sd, out pStream)); return pStream; } #endregion //CASRemoval:[System.Security.SuppressUnmanagedCodeSecurity, DllImport("DllImport.MilCore")] [DllImport(DllImport.MilCore)]//CASRemoval: private extern static int /* HRESULT */ MILIStreamWrite(IntPtr pStream, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]byte[] buffer, uint cb, out uint cbWritten); } #endregion } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2002-2003 // // File: StreamAsIStream.cs //----------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages using System.Windows.Media; using System.Security; using System.Security.Permissions; using System; using MS.Internal; using MS.Win32; using System.Reflection; using System.Collections; using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Internal; using MS.Internal.PresentationCore; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods; // TODOTODO Make our own namespace for internal stuff. namespace System.Windows.Media { #region StreamDescriptor [StructLayout(LayoutKind.Sequential)] internal struct StreamDescriptor { internal delegate void Dispose(ref StreamDescriptor pSD); internal delegate int Read(ref StreamDescriptor pSD, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out]byte[] buffer, uint cb, out uint cbRead); internal unsafe delegate int Seek(ref StreamDescriptor pSD, long offset, uint origin, long* plibNewPostion); internal delegate int Stat(ref StreamDescriptor pSD, out System.Runtime.InteropServices.ComTypes.STATSTG statstg, uint grfStatFlag); internal delegate int Write(ref StreamDescriptor pSD, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]byte[] buffer, uint cb, out uint cbWritten); internal delegate int CopyTo(ref StreamDescriptor pSD, IntPtr pstm, long cb, out long cbRead, out long cbWritten); internal delegate int SetSize(ref StreamDescriptor pSD, long value); internal delegate int Revert(ref StreamDescriptor pSD); internal delegate int Commit(ref StreamDescriptor pSD, UInt32 grfCommitFlags); internal delegate int LockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType); internal delegate int UnlockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType); internal delegate int Clone(ref StreamDescriptor pSD, out IntPtr stream); internal delegate int CanWrite(ref StreamDescriptor pSD, out bool canWrite); internal delegate int CanSeek(ref StreamDescriptor pSD, out bool canSeek); internal Dispose pfnDispose; internal Read pfnRead; internal Seek pfnSeek; internal Stat pfnStat; internal Write pfnWrite; internal CopyTo pfnCopyTo; internal SetSize pfnSetSize; internal Commit pfnCommit; internal Revert pfnRevert; internal LockRegion pfnLockRegion; internal UnlockRegion pfnUnlockRegion; internal Clone pfnClone; internal CanWrite pfnCanWrite; internal CanSeek pfnCanSeek; ////// Critical: This code calls into link demand protected GCHandle /// TreatAsSafe: This code is ok to expose especially since it does not expose the handle /// [SecurityCritical, SecurityTreatAsSafe] internal static void StaticDispose(ref StreamDescriptor pSD) { Debug.Assert(((IntPtr)pSD.m_handle) != IntPtr.Zero, "If this asserts fires: why is it firing. It might be legal in future."); StreamAsIStream sais = (StreamAsIStream)(pSD.m_handle.Target); ((System.Runtime.InteropServices.GCHandle)(pSD.m_handle)).Free(); } internal System.Runtime.InteropServices.GCHandle m_handle; } #endregion #region StaticPtrs ////// We need to keep the delegates alive. /// internal static class StaticPtrs { ////// Critical - this method has an unsafe block and references StreamAsIStream.Seek /// TreatAsSafe - referenced function pointer is well known /// [SecurityCritical, SecurityTreatAsSafe] static StaticPtrs() { StaticPtrs.pfnDispose = new StreamDescriptor.Dispose(StreamDescriptor.StaticDispose); StaticPtrs.pfnClone = new StreamDescriptor.Clone(StreamAsIStream.Clone); StaticPtrs.pfnCommit = new StreamDescriptor.Commit(StreamAsIStream.Commit); StaticPtrs.pfnCopyTo = new StreamDescriptor.CopyTo(StreamAsIStream.CopyTo); StaticPtrs.pfnLockRegion = new StreamDescriptor.LockRegion(StreamAsIStream.LockRegion); StaticPtrs.pfnRead = new StreamDescriptor.Read(StreamAsIStream.Read); StaticPtrs.pfnRevert = new StreamDescriptor.Revert(StreamAsIStream.Revert); unsafe { StaticPtrs.pfnSeek = new StreamDescriptor.Seek(StreamAsIStream.Seek); } StaticPtrs.pfnSetSize = new StreamDescriptor.SetSize(StreamAsIStream.SetSize); StaticPtrs.pfnStat = new StreamDescriptor.Stat(StreamAsIStream.Stat); StaticPtrs.pfnUnlockRegion = new StreamDescriptor.UnlockRegion(StreamAsIStream.UnlockRegion); StaticPtrs.pfnWrite = new StreamDescriptor.Write(StreamAsIStream.Write); StaticPtrs.pfnCanWrite = new StreamDescriptor.CanWrite(StreamAsIStream.CanWrite); StaticPtrs.pfnCanSeek = new StreamDescriptor.CanSeek(StreamAsIStream.CanSeek); } internal static StreamDescriptor.Dispose pfnDispose; internal static StreamDescriptor.Read pfnRead; internal static StreamDescriptor.Seek pfnSeek; internal static StreamDescriptor.Stat pfnStat; internal static StreamDescriptor.Write pfnWrite; internal static StreamDescriptor.CopyTo pfnCopyTo; internal static StreamDescriptor.SetSize pfnSetSize; internal static StreamDescriptor.Commit pfnCommit; internal static StreamDescriptor.Revert pfnRevert; internal static StreamDescriptor.LockRegion pfnLockRegion; internal static StreamDescriptor.UnlockRegion pfnUnlockRegion; internal static StreamDescriptor.Clone pfnClone; internal static StreamDescriptor.CanWrite pfnCanWrite; internal static StreamDescriptor.CanSeek pfnCanSeek; } #endregion #region StreamAsIStream //CASRemoval:[System.Security.SuppressUnmanagedCodeSecurity] internal class StreamAsIStream { #region Instance Data const int STREAM_SEEK_SET = 0x0; const int STREAM_SEEK_CUR = 0x1; const int STREAM_SEEK_END = 0x2; protected System.IO.Stream dataStream; private Exception _lastException; // to support seeking ahead of the stream length... private long virtualPosition = -1; #endregion #region Constructor private StreamAsIStream(System.IO.Stream dataStream) { this.dataStream = dataStream; } #endregion #region Private Methods private void ActualizeVirtualPosition() { if (virtualPosition == -1) { return; } if (virtualPosition > dataStream.Length) { dataStream.SetLength(virtualPosition); } dataStream.Position = virtualPosition; virtualPosition = -1; } #endregion #region StreamFunctions public int Clone(out IntPtr stream) { stream = IntPtr.Zero; #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } public int Commit(uint grfCommitFlags) { #pragma warning disable 6500 try { Verify(); dataStream.Flush(); // Extend the length of the file if needed. ActualizeVirtualPosition(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int CopyTo(IntPtr /* IStream */ pstm, long cb, out long cbRead, out long cbWritten) { int hr = NativeMethods.S_OK; uint bufsize = 4096; // one page byte[] buffer = new byte[bufsize]; cbWritten = 0; cbRead = 0; #pragma warning disable 6500 try { Verify(); while (cbWritten < cb) { uint toRead = bufsize; if (cbWritten + toRead > cb) { toRead = (uint) (cb - cbWritten); } uint read = 0; hr = Read(buffer, toRead, out read); if (read == 0) { break; } cbRead += read; uint written = 0; hr = MILIStreamWrite(pstm, buffer, read, out written); if (written != read) { return hr; } cbWritten += read; } } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return hr; } public int LockRegion(long libOffset, long cb, uint dwLockType) { #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } public int Read(byte[] buffer, uint cb, out uint cbRead) { cbRead = 0; #pragma warning disable 6500 try { Verify(); ActualizeVirtualPosition(); cbRead = (uint) dataStream.Read(buffer, 0, (int) cb); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int Revert() { #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } ////// Critical - this method is unsafe - it cannot warrant the validity of the given pointer /// [SecurityCritical] public unsafe int Seek(long offset, uint origin, long * plibNewPostion) { #pragma warning disable 6500 try { Verify(); long pos = virtualPosition; if (virtualPosition == -1) { pos = dataStream.Position; } long len = dataStream.Length; switch (origin) { case STREAM_SEEK_SET: if (offset <= len) { dataStream.Position = offset; virtualPosition = -1; } else { virtualPosition = offset; } break; case STREAM_SEEK_END: if (offset <= 0) { dataStream.Position = len + offset; virtualPosition = -1; } else { virtualPosition = len + offset; } break; case STREAM_SEEK_CUR: if (offset+pos <= len) { dataStream.Position = pos + offset; virtualPosition = -1; } else { virtualPosition = offset + pos; } break; } if (plibNewPostion!=null) { if (virtualPosition != -1) { *plibNewPostion = virtualPosition; } else { *plibNewPostion = dataStream.Position; } } } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int SetSize(long value) { #pragma warning disable 6500 try { Verify(); dataStream.SetLength(value); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int Stat(out System.Runtime.InteropServices.ComTypes.STATSTG statstg, uint grfStatFlag) { System.Runtime.InteropServices.ComTypes.STATSTG statstgOut = new System.Runtime.InteropServices.ComTypes.STATSTG(); statstg = statstgOut; #pragma warning disable 6500 try { Verify(); statstgOut.type = 2; // STGTY_STREAM statstgOut.cbSize = dataStream.Length; statstgOut.grfLocksSupported = 2; //LOCK_EXCLUSIVE statstgOut.pwcsName = null; statstg = statstgOut; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int UnlockRegion(long libOffset, long cb, uint dwLockType) { #pragma warning disable 6500 try { Verify(); } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.E_NOTIMPL; } public int Write(byte[] buffer, uint cb, out uint cbWritten) { cbWritten = 0; #pragma warning disable 6500 try { Verify(); ActualizeVirtualPosition(); dataStream.Write(buffer, 0, (int) cb); cbWritten = cb; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int CanWrite(out bool canWrite) { canWrite = false; #pragma warning disable 6500 try { Verify(); canWrite = dataStream.CanWrite; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } public int CanSeek(out bool canSeek) { canSeek = false; #pragma warning disable 6500 try { Verify(); canSeek = dataStream.CanSeek; } catch (Exception e) { // store the last exception _lastException = e; return SecurityHelper.GetHRForException(e); } #pragma warning restore 6500 return NativeMethods.S_OK; } #endregion #region Verify private void Verify() { if (this.dataStream == null) { throw new System.ObjectDisposedException(SR.Get(SRID.Media_StreamClosed)); } } #endregion #region Delegate Implemetations ////// Critical: This code calls into link demand protected GCHandle /// TreatAsSafe: This code is ok to expose /// [SecurityCritical,SecurityTreatAsSafe] internal static StreamAsIStream FromSD(ref StreamDescriptor sd) { Debug.Assert(((IntPtr)sd.m_handle) != IntPtr.Zero, "Stream is disposed."); System.Runtime.InteropServices.GCHandle handle = (System.Runtime.InteropServices.GCHandle)(sd.m_handle); return (StreamAsIStream)(handle.Target); } internal static int Clone(ref StreamDescriptor pSD, out IntPtr stream) { return (StreamAsIStream.FromSD(ref pSD)).Clone(out stream); } internal static int Commit(ref StreamDescriptor pSD, UInt32 grfCommitFlags) { return (StreamAsIStream.FromSD(ref pSD)).Commit(grfCommitFlags); } internal static int CopyTo(ref StreamDescriptor pSD, IntPtr pstm, long cb, out long cbRead, out long cbWritten) { return (StreamAsIStream.FromSD(ref pSD)).CopyTo(pstm, cb, out cbRead, out cbWritten); } internal static int LockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType) { return (StreamAsIStream.FromSD(ref pSD)).LockRegion(libOffset, cb, dwLockType); } internal static int Read(ref StreamDescriptor pSD, byte[] buffer, uint cb, out uint cbRead) { return (StreamAsIStream.FromSD(ref pSD)).Read(buffer, cb, out cbRead); } internal static int Revert(ref StreamDescriptor pSD) { return (StreamAsIStream.FromSD(ref pSD)).Revert(); } ////// Critical - this method is unsafe - it cannot warrant the validity of the given pointer /// [SecurityCritical] internal unsafe static int Seek(ref StreamDescriptor pSD, long offset, uint origin, long* plibNewPostion) { return (StreamAsIStream.FromSD(ref pSD)).Seek(offset, origin, plibNewPostion); } internal static int SetSize(ref StreamDescriptor pSD, long value) { return (StreamAsIStream.FromSD(ref pSD)).SetSize(value); } internal static int Stat(ref StreamDescriptor pSD, out System.Runtime.InteropServices.ComTypes.STATSTG statstg, uint grfStatFlag) { return (StreamAsIStream.FromSD(ref pSD)).Stat(out statstg, grfStatFlag); } internal static int UnlockRegion(ref StreamDescriptor pSD, long libOffset, long cb, uint dwLockType) { return (StreamAsIStream.FromSD(ref pSD)).UnlockRegion(libOffset, cb, dwLockType); } internal static int Write(ref StreamDescriptor pSD, byte[] buffer, uint cb, out uint cbWritten) { return (StreamAsIStream.FromSD(ref pSD)).Write(buffer, cb, out cbWritten); } internal static int CanWrite(ref StreamDescriptor pSD, out bool canWrite) { return (StreamAsIStream.FromSD(ref pSD)).CanWrite(out canWrite); } internal static int CanSeek(ref StreamDescriptor pSD, out bool canSeek) { return (StreamAsIStream.FromSD(ref pSD)).CanSeek(out canSeek); } #endregion // Takes an IStream that is potentially not seekable and returns // a seekable memory stream that is a copy of it. ////// Critical - calls unmanaged code, takes unmanaged pointer argument /// [SecurityCritical] internal static IntPtr IStreamMemoryFrom(IntPtr comStream) { IntPtr pIStream = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { if (HRESULT.Failed(UnsafeNativeMethods.WICImagingFactory.CreateStream(myFactory.ImagingFactoryPtr, out pIStream))) { return IntPtr.Zero; } if (HRESULT.Failed(UnsafeNativeMethods.WICStream.InitializeFromIStream(pIStream, comStream))) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pIStream); return IntPtr.Zero; } } return pIStream; } ////// Critical - calls unmanaged code, accepts unmanaged pointers /// [SecurityCritical] internal static IntPtr IStreamFrom(IntPtr memoryBuffer, int bufferSize) { IntPtr pIStream = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { if (HRESULT.Failed(UnsafeNativeMethods.WICImagingFactory.CreateStream(myFactory.ImagingFactoryPtr, out pIStream))) { return IntPtr.Zero; } if (HRESULT.Failed(UnsafeNativeMethods.WICStream.InitializeFromMemory(pIStream, memoryBuffer, (uint) bufferSize))) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pIStream); return IntPtr.Zero; } } return pIStream; } #region IStreamFrom System.IO.Stream ////// Critical - calls critical code, create unmanaged structures /// [SecurityCritical] internal static IntPtr IStreamFrom(System.IO.Stream stream) { if (stream == null) { throw new System.ArgumentNullException("stream"); } IntPtr pStream = IntPtr.Zero; StreamAsIStream sais = new StreamAsIStream(stream); StreamDescriptor sd = new StreamDescriptor(); sd.pfnDispose = StaticPtrs.pfnDispose; sd.pfnClone = StaticPtrs.pfnClone; sd.pfnCommit = StaticPtrs.pfnCommit; sd.pfnCopyTo = StaticPtrs.pfnCopyTo; sd.pfnLockRegion = StaticPtrs.pfnLockRegion; sd.pfnRead = StaticPtrs.pfnRead; sd.pfnRevert = StaticPtrs.pfnRevert; unsafe { sd.pfnSeek = StaticPtrs.pfnSeek; } sd.pfnSetSize = StaticPtrs.pfnSetSize; sd.pfnStat = StaticPtrs.pfnStat; sd.pfnUnlockRegion = StaticPtrs.pfnUnlockRegion; sd.pfnWrite = StaticPtrs.pfnWrite; sd.pfnCanWrite = StaticPtrs.pfnCanWrite; sd.pfnCanSeek = StaticPtrs.pfnCanSeek; sd.m_handle = System.Runtime.InteropServices.GCHandle.Alloc(sais, System.Runtime.InteropServices.GCHandleType.Normal); HRESULT.Check(UnsafeNativeMethods.MilCoreApi.MILCreateStreamFromStreamDescriptor(ref sd, out pStream)); return pStream; } #endregion //CASRemoval:[System.Security.SuppressUnmanagedCodeSecurity, DllImport("DllImport.MilCore")] [DllImport(DllImport.MilCore)]//CASRemoval: private extern static int /* HRESULT */ MILIStreamWrite(IntPtr pStream, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]byte[] buffer, uint cb, out uint cbWritten); } #endregion } // 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
- InstanceData.cs
- PeerContact.cs
- SegmentInfo.cs
- Unit.cs
- NotFiniteNumberException.cs
- DoubleConverter.cs
- ParserOptions.cs
- CalendarSelectionChangedEventArgs.cs
- Quaternion.cs
- XmlAttribute.cs
- CaretElement.cs
- Italic.cs
- CachingHintValidation.cs
- GPStream.cs
- SmtpNegotiateAuthenticationModule.cs
- XmlParserContext.cs
- HtmlTableRow.cs
- CachedTypeface.cs
- WebPartConnectionsCancelVerb.cs
- RectAnimationClockResource.cs
- EventProxy.cs
- RemoteX509AsymmetricSecurityKey.cs
- smtppermission.cs
- Soap.cs
- CaseCqlBlock.cs
- ProcessManager.cs
- TranslateTransform.cs
- DynamicValueConverter.cs
- TailPinnedEventArgs.cs
- XmlWrappingWriter.cs
- WebPartEditorCancelVerb.cs
- WebPartUserCapability.cs
- ControlCommandSet.cs
- SmtpException.cs
- ValidationPropertyAttribute.cs
- AnnotationMap.cs
- CalculatedColumn.cs
- SmiMetaData.cs
- ButtonColumn.cs
- WebPartActionVerb.cs
- TextElementEnumerator.cs
- CatalogPart.cs
- NumberSubstitution.cs
- BitmapImage.cs
- SqlConnectionPoolProviderInfo.cs
- StringValueSerializer.cs
- CompositeCollectionView.cs
- SystemSounds.cs
- CustomLineCap.cs
- PagedDataSource.cs
- XPathSelfQuery.cs
- TripleDESCryptoServiceProvider.cs
- TableDesigner.cs
- SqlDuplicator.cs
- UiaCoreProviderApi.cs
- PanelDesigner.cs
- LogRestartAreaEnumerator.cs
- EncoderParameters.cs
- RelationshipDetailsCollection.cs
- ZipIOCentralDirectoryDigitalSignature.cs
- ContourSegment.cs
- RenderDataDrawingContext.cs
- CapabilitiesState.cs
- KoreanLunisolarCalendar.cs
- DNS.cs
- QueryCursorEventArgs.cs
- XPathEmptyIterator.cs
- CompiledELinqQueryState.cs
- Translator.cs
- WebControlsSection.cs
- Graphics.cs
- ExcCanonicalXml.cs
- XPathNode.cs
- GestureRecognizer.cs
- QilChoice.cs
- Repeater.cs
- ProxyWebPartManager.cs
- WorkflowRuntimeEndpoint.cs
- Clock.cs
- ClientTargetSection.cs
- TemplateXamlParser.cs
- SchemaTableColumn.cs
- OlePropertyStructs.cs
- Point3DAnimationBase.cs
- MailMessageEventArgs.cs
- TypeDescriptionProviderAttribute.cs
- CharUnicodeInfo.cs
- ClickablePoint.cs
- PostBackOptions.cs
- ScrollData.cs
- PointAnimationUsingPath.cs
- COM2PropertyDescriptor.cs
- SoapWriter.cs
- BaseTemplateCodeDomTreeGenerator.cs
- WindowsListView.cs
- ObjectDataSourceDisposingEventArgs.cs
- XmlSchemaElement.cs
- Point3DCollection.cs
- Soap12FormatExtensions.cs
- DirectionalLight.cs