Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / MS / Internal / IO / Packaging / CompoundFile / NativeCompoundFileAPIs.cs / 1 / NativeCompoundFileAPIs.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // The COM and P/Invoke interop code necessary for the managed compound // file layer to call the existing APIs in OLE32.DLL. // // Note that not everything is properly ported, for example the SNB type // used in several IStorage methods is just ignored. // // History: // 05/10/2002: RogerCh: Initial creation. // 07/31/2002: RogerCh: Add LockBytes support, suppress unmanaged code security. // 05/20/2003: RogerCh: Ported to WCP tree. // 05/28/2003: RogerCh: Removed name checks - now handled by LongNameManager // 02/10/2006: YoungGK: Separated the security suppressed interfaces and APIs // Created the wrapper class that calls unmanaged APIs // //----------------------------------------------------------------------------- using System; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Windows; using MS.Internal.Interop; using MS.Internal.WindowsBase; // for SecurityHelper using CultureInfo = System.Globalization.CultureInfo; namespace MS.Internal.IO.Packaging.CompoundFile { //// Critical: This class serves as a wrapper on top of several unmanaged CompoundFile // interfaces and API calls. These interfaces and APIs has suppress unamanged // code attribute set. // It is up to this class to ensure that the only calls that can go through must // be either done in Full Trust or with CompoundFileIOPermission. // This class exposes several internal APIs and interfaces built on top of classes that // demand the CompoundFileIOPermission and then call through the matching member of // the unsafe APIs and interfaces. // SecurityTreatAsSafe: Demands CompoundFileIOPermission before it makes any calls to // unmanaged APIs // [SecurityCritical(SecurityCriticalScope.Everything), SecurityTreatAsSafe] internal static class SafeNativeCompoundFileMethods { ////// Utility function to update a grfMode value based on FileAccess. /// 6/12/2002: Fixes bug #4938, 4960, 5096, 4858 /// /// FileAccess we're translating /// Mode flag parameter to modify //// SecurityTreatAsSafe: Makes NO call to security suppressed unmanaged code // internal static void UpdateModeFlagFromFileAccess( FileAccess access, ref int grfMode ) { // Supporting write-only scenarios container-wide gets tricky and it // is rarely used. Don't support it for now because of poor // cost/benefit ratio. if( FileAccess.Write == access ) throw new NotSupportedException( SR.Get(SRID.WriteOnlyUnsupported)); // Generate STGM from FileAccess // STGM_READ is 0x00, so it's "by default" if( ( FileAccess.ReadWrite == (access & FileAccess.ReadWrite) ) || ( (FileAccess.Read | FileAccess.Write) == (access & (FileAccess.Read | FileAccess.Write))) ) { grfMode |= SafeNativeCompoundFileConstants.STGM_READWRITE; } else if( FileAccess.Write == (access & FileAccess.Write) ) { grfMode |= SafeNativeCompoundFileConstants.STGM_WRITE; } else if( FileAccess.Read != (access & FileAccess.Read)) { throw new ArgumentException( SR.Get(SRID.FileAccessInvalid)); } } internal static int SafeStgCreateDocfileOnStream( Stream s, int grfMode, out IStorage ppstgOpen ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(s != null, "s cannot be null"); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream lockByteStream = new UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream(s); int result; result = UnsafeNativeCompoundFileMethods.StgCreateDocfileOnILockBytes( (UnsafeNativeCompoundFileMethods.UnsafeNativeILockBytes) lockByteStream, grfMode, 0, // Must be zero out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppstgOpen = new SafeIStorageImplementation(storage, lockByteStream); else { ppstgOpen = null; lockByteStream.Dispose(); } return result; } internal static int SafeStgOpenStorageOnStream( Stream s, int grfMode, out IStorage ppstgOpen ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(s != null, "s cannot be null"); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream lockByteStream = new UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream(s); int result; result = UnsafeNativeCompoundFileMethods.StgOpenStorageOnILockBytes( (UnsafeNativeCompoundFileMethods.UnsafeNativeILockBytes) lockByteStream, null, grfMode, new IntPtr(0), // Pointer to SNB struct, not marshalled, must be null. 0, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppstgOpen = new SafeIStorageImplementation(storage); else { ppstgOpen = null; lockByteStream.Dispose(); } return result; } internal static int SafeStgCreateStorageEx( string pwcsName, //Pointer to path of compound file to create int grfMode, // Specifies the access mode for opening the storage object int stgfmt, // Specifies the storage file format, 5 is DocFile int grfAttrs, // Reserved; must be zero IntPtr pStgOptions,// Pointer to STGOPTIONS, not marshalled, must use NULL. IntPtr reserved2, // Reserved; must be null ref Guid riid, // Specifies the GUID of the interface pointer out IStorage ppObjectOpen //Pointer to an interface pointer ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = UnsafeNativeCompoundFileMethods.StgCreateStorageEx( pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, reserved2, ref riid, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppObjectOpen = new SafeIStorageImplementation(storage); else ppObjectOpen = null; return result; } internal static int SafeStgOpenStorageEx( string pwcsName, //Pointer to path of compound file to create int grfMode, // Specifies the access mode for opening the storage object int stgfmt, // Specifies the storage file format, 5 is DocFile int grfAttrs, // Reserved; must be zero IntPtr pStgOptions,// Pointer to STGOPTIONS, not marshalled, must use NULL. IntPtr reserved2, // Reserved; must be null ref Guid riid, // Specifies the GUID of the interface pointer out IStorage ppObjectOpen //Pointer to an interface pointer ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = UnsafeNativeCompoundFileMethods.StgOpenStorageEx( pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, reserved2, ref riid, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppObjectOpen = new SafeIStorageImplementation(storage); else ppObjectOpen = null; return result; } //// Critical: This method calls security suppressed unmanaged CompoundFile code. // ComoundFileIOPermission needs to be demanded to ensure that the only calls // that can go through must be either done in Full Trust or with under assertion of // CompoundFileIOPermission. // SecurityTreatAsSafe: Demands CompoundFileIOPermission before it makes any calls to // unmanaged APIs // internal static int SafePropVariantClear(ref PROPVARIANT pvar) { SecurityHelper.DemandCompoundFileIOPermission(); return UnsafeNativeCompoundFileMethods.PropVariantClear(ref pvar); } private class SafeIStorageImplementation : IStorage, IPropertySetStorage, IDisposable { internal SafeIStorageImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage) : this(storage, null) { } internal SafeIStorageImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage, UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream lockBytesStream) { SecurityHelper.DemandCompoundFileIOPermission(); if (storage == null) { throw new ArgumentNullException("storage"); } _unsafeStorage = storage; _unsafePropertySetStorage = (UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertySetStorage) _unsafeStorage; _unsafeLockByteStream = lockBytesStream; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeStorage != null)) { // We only need to release IStorage only not IPropertySetStorage // since it shares once instance of RCW MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeStorage); // If the storage was originally opened on lockbyte implementation // we need to dispose it as well if (_unsafeLockByteStream != null) { _unsafeLockByteStream.Dispose(); } } } finally { _unsafeStorage = null; _unsafePropertySetStorage = null; _unsafeLockByteStream = null; } } // // IStorage Implementation // int IStorage.CreateStream( string pwcsName, int grfMode, int reserved1, int reserved2, out IStream ppstm ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream; int result; result = _unsafeStorage.CreateStream( pwcsName, grfMode, reserved1, reserved2, out stream); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstm = new SafeIStreamImplementation(stream); } else { ppstm = null; } return result; } int IStorage.OpenStream( string pwcsName, int reserved1, int grfMode, int reserved2, out IStream ppstm ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream; int result; result = _unsafeStorage.OpenStream( pwcsName, reserved1, grfMode, reserved2, out stream); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstm = new SafeIStreamImplementation(stream); } else { ppstm = null; } return result; } int IStorage.CreateStorage( string pwcsName, int grfMode, int reserved1, int reserved2, out IStorage ppstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = _unsafeStorage.CreateStorage( pwcsName, grfMode, reserved1, reserved2, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstg = new SafeIStorageImplementation(storage); } else { ppstg = null; } return result; } int IStorage.OpenStorage( string pwcsName, IStorage pstgPriority, int grfMode, IntPtr snbExclude, // Not properly translated, but must be NULL anyway int reserved, out IStorage ppstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = _unsafeStorage.OpenStorage( pwcsName, pstgPriority == null ? null : ((SafeIStorageImplementation) pstgPriority)._unsafeStorage, grfMode, snbExclude, reserved, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstg = new SafeIStorageImplementation(storage); } else { ppstg = null; } return result; } void IStorage.CopyTo( int ciidExclude, Guid[] rgiidExclude, IntPtr snbExclude, // Not properly translated, use NULL to avoid `blow-up IStorage ppstg ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(ppstg != null, "ppstg cannot be null"); _unsafeStorage.CopyTo( ciidExclude, rgiidExclude, snbExclude, ((SafeIStorageImplementation) ppstg)._unsafeStorage); } void IStorage.MoveElementTo( string pwcsName, IStorage pstgDest, string pwcsNewName, int grfFlags ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(pstgDest != null, "pstgDest cannot be null"); _unsafeStorage.MoveElementTo( pwcsName, ((SafeIStorageImplementation) pstgDest)._unsafeStorage, pwcsNewName, grfFlags); } void IStorage.Commit( int grfCommitFlags ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.Commit( grfCommitFlags); } void IStorage.Revert() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.Revert(); } void IStorage.EnumElements( int reserved1, IntPtr reserved2, int reserved3, out IEnumSTATSTG ppEnum ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG enumSTATSTG; _unsafeStorage.EnumElements( reserved1, reserved2, reserved3, out enumSTATSTG); if (enumSTATSTG != null) ppEnum = new SafeIEnumSTATSTGImplementation(enumSTATSTG); else ppEnum = null; } void IStorage.DestroyElement( string pwcsName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.DestroyElement( pwcsName); } void IStorage.RenameElement( string pwcsOldName, string pwcsNewName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.RenameElement( pwcsOldName, pwcsNewName); } void IStorage.SetElementTimes( string pwcsName, System.Runtime.InteropServices.ComTypes.FILETIME pctime, System.Runtime.InteropServices.ComTypes.FILETIME patime, System.Runtime.InteropServices.ComTypes.FILETIME pmtime ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.SetElementTimes( pwcsName, pctime, patime, pmtime); } void IStorage.SetClass( ref Guid clsid ) // Hopefully "ref" is how I tell it to use a pointer { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.SetClass( ref clsid ); } void IStorage.SetStateBits( int grfStateBits, int grfMask ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.SetStateBits( grfStateBits, grfMask); } void IStorage.Stat( out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.Stat( out pstatstg, grfStatFlag); } void IPropertySetStorage.Create( ref Guid rfmtid, ref Guid pclsid, UInt32 grfFlags, UInt32 grfMode, out IPropertyStorage ppprstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage propertyStorage; _unsafePropertySetStorage.Create( ref rfmtid, ref pclsid, grfFlags, grfMode, out propertyStorage ); if (propertyStorage != null) ppprstg = new SafeIPropertyStorageImplementation(propertyStorage); else ppprstg = null; } int IPropertySetStorage.Open( ref Guid rfmtid, UInt32 grfMode, out IPropertyStorage ppprstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage propertyStorage; int hr = _unsafePropertySetStorage.Open( ref rfmtid, grfMode, out propertyStorage ); if (propertyStorage != null) ppprstg = new SafeIPropertyStorageImplementation(propertyStorage); else ppprstg = null; return hr; } void IPropertySetStorage.Delete( ref Guid rfmtid ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertySetStorage.Delete( ref rfmtid ); } void IPropertySetStorage.Enum( out IEnumSTATPROPSETSTG ppenum ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG enumSTATPROPSETSTG; _unsafePropertySetStorage.Enum( out enumSTATPROPSETSTG ); if (enumSTATPROPSETSTG != null) ppenum = new SafeIEnumSTATPROPSETSTGImplementation(enumSTATPROPSETSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertySetStorage _unsafePropertySetStorage; private UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage _unsafeStorage; private UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream _unsafeLockByteStream; } private class SafeIStreamImplementation : IStream, IDisposable { internal SafeIStreamImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream) { _unsafeStream = stream; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeStream != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeStream); } } finally { _unsafeStream = null; } } // // IStream Implementation // void IStream.Read(Byte[] pv, int cb, out int pcbRead) { SecurityHelper.DemandCompoundFileIOPermission(); if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.Read(pv, cb, out pcbRead); } void IStream.Write(Byte[] pv, int cb, out int pcbWritten) { SecurityHelper.DemandCompoundFileIOPermission(); if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.Write(pv, cb, out pcbWritten); } // IStream portion void IStream.Seek(long dlibMove, int dwOrigin, out long plibNewPosition) { SecurityHelper.DemandCompoundFileIOPermission(); if (dwOrigin < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "dwOrigin", dwOrigin.ToString(CultureInfo.InvariantCulture))); } if (dlibMove < 0 && dwOrigin == SafeNativeCompoundFileConstants.STREAM_SEEK_SET) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "dlibMove", dlibMove.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.Seek(dlibMove, dwOrigin, out plibNewPosition); } void IStream.SetSize(long libNewSize) { SecurityHelper.DemandCompoundFileIOPermission(); if (libNewSize < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "libNewSize", libNewSize.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.SetSize(libNewSize); } void IStream.CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(pstm != null, "pstm cannot be null"); if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.CopyTo(((SafeIStreamImplementation) pstm)._unsafeStream, cb, out pcbRead, out pcbWritten); } void IStream.Commit(int grfCommitFlags) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStream.Commit(grfCommitFlags); } void IStream.Revert() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStream.Revert(); } void IStream.LockRegion(long libOffset, long cb, int dwLockType) { SecurityHelper.DemandCompoundFileIOPermission(); if (libOffset < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "libOffset", libOffset.ToString(CultureInfo.InvariantCulture))); } if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.LockRegion(libOffset, cb, dwLockType); } void IStream.UnlockRegion(long libOffset, long cb, int dwLockType) { SecurityHelper.DemandCompoundFileIOPermission(); if (libOffset < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "libOffset", libOffset.ToString(CultureInfo.InvariantCulture))); } if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.UnlockRegion(libOffset, cb, dwLockType); } void IStream.Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStream.Stat(out pstatstg, grfStatFlag); } void IStream.Clone(out IStream ppstm) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream; _unsafeStream.Clone(out stream); if (stream != null) { ppstm = new SafeIStreamImplementation(stream); } else { ppstm = null; } } private UnsafeNativeCompoundFileMethods.UnsafeNativeIStream _unsafeStream; } private class SafeIEnumSTATPROPSETSTGImplementation : IEnumSTATPROPSETSTG, IDisposable { internal SafeIEnumSTATPROPSETSTGImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG enumSTATPROPSETSTG) { _unsafeEnumSTATPROPSETSTG = enumSTATPROPSETSTG; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeEnumSTATPROPSETSTG != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeEnumSTATPROPSETSTG); } } finally { _unsafeEnumSTATPROPSETSTG = null; } } // // The caller must allocate an array of celt STATPROPSETSTG structures // to receive the results. // // This method is PreserveSig because it can return a non-0 success // code; S_FALSE => fewer than celt elements were returned. // int IEnumSTATPROPSETSTG.Next( UInt32 celt, STATPROPSETSTG rgelt, out UInt32 pceltFetched ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafeEnumSTATPROPSETSTG.Next( celt, rgelt, out pceltFetched ); } void IEnumSTATPROPSETSTG.Skip(UInt32 celt) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSETSTG.Skip(celt); } void IEnumSTATPROPSETSTG.Reset() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSETSTG.Reset(); } void IEnumSTATPROPSETSTG.Clone(out IEnumSTATPROPSETSTG ppenum) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG enumSTATPROPSETSTG; _unsafeEnumSTATPROPSETSTG.Clone(out enumSTATPROPSETSTG); if (enumSTATPROPSETSTG != null) ppenum = new SafeIEnumSTATPROPSETSTGImplementation(enumSTATPROPSETSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG _unsafeEnumSTATPROPSETSTG; } private class SafeIPropertyStorageImplementation : IPropertyStorage, IDisposable { internal SafeIPropertyStorageImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage propertyStorage) { _unsafePropertyStorage = propertyStorage; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafePropertyStorage != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafePropertyStorage); } } finally { _unsafePropertyStorage = null; } } // // We preserve the HRESULT on this method because we need to distinguish // between S_OK (we got the properties we asked for) and S_FALSE (none of // the properties exist). // int IPropertyStorage.ReadMultiple( UInt32 cpspec, PROPSPEC[] rgpspec, PROPVARIANT[] rgpropvar ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafePropertyStorage.ReadMultiple( cpspec, rgpspec, rgpropvar ); } void IPropertyStorage.WriteMultiple( UInt32 cpspec, PROPSPEC[] rgpspec, PROPVARIANT[] rgpropvar, uint propidNameFirst ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.WriteMultiple( cpspec, rgpspec, rgpropvar, propidNameFirst ); } void IPropertyStorage.DeleteMultiple( UInt32 cpspec, PROPSPEC[] rgpspec ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.DeleteMultiple( cpspec, rgpspec ); } void IPropertyStorage.ReadPropertyNames( UInt32 cpropid, UInt32[] rgpropid, string[] rglpwstrName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.ReadPropertyNames( cpropid, rgpropid, rglpwstrName ); } void IPropertyStorage.WritePropertyNames( UInt32 cpropid, UInt32[] rgpropid, string[] rglpwstrName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.WritePropertyNames( cpropid, rgpropid, rglpwstrName ); } void IPropertyStorage.DeletePropertyNames( UInt32 cpropid, UInt32[] rgpropid ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.DeletePropertyNames( cpropid, rgpropid ); } void IPropertyStorage.Commit( UInt32 grfCommitFlags ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.Commit( grfCommitFlags ); } void IPropertyStorage.Revert() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.Revert(); } void IPropertyStorage.Enum( out IEnumSTATPROPSTG ppenum ) { SecurityHelper.DemandCompoundFileIOPermission(); #if Using_SafeIPropertyStorageImplementation_Enum UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG unsafeEnumSTATPROPSTG; _unsafePropertyStorage.Enum( out unsafeEnumSTATPROPSTG ); if (unsafeEnumSTATPROPSTG != null) ppenum = new SafeIEnumSTATPROPSTGImplementation(unsafeEnumSTATPROPSTG); else #endif ppenum = null; } void IPropertyStorage.SetTimes( ref System.Runtime.InteropServices.ComTypes.FILETIME pctime, ref System.Runtime.InteropServices.ComTypes.FILETIME patime, ref System.Runtime.InteropServices.ComTypes.FILETIME pmtime ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.SetTimes( ref pctime, ref patime, ref pmtime ); } void IPropertyStorage.SetClass( ref Guid clsid ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.SetClass( ref clsid ); } void IPropertyStorage.Stat( out STATPROPSETSTG pstatpsstg ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.Stat( out pstatpsstg ); } private UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage _unsafePropertyStorage; } #if Using_SafeIPropertyStorageImplementation_Enum private class SafeIEnumSTATPROPSTGImplementation : IEnumSTATPROPSTG { internal SafeIEnumSTATPROPSTGImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG enumSTATPROPSTG) { _unsafeEnumSTATPROPSTG= enumSTATPROPSTG; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeEnumSTATPROPSTG != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeEnumSTATPROPSTG); } } finally { _unsafeEnumSTATPROPSTG = null; } } // // The caller must allocate an array of celt STATPROPSTG structures // to receive the results. // // This method is PreserveSig because it can return a non-0 success // code; S_FALSE => fewer than celt elements were returned. // int IEnumSTATPROPSTG.Next( UInt32 celt, STATPROPSTG rgelt, out UInt32 pceltFetched ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafeEnumSTATPROPSTG.Next( celt, rgelt, out pceltFetched ); } void IEnumSTATPROPSTG.Skip(UInt32 celt) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSTG.Skip(celt); } void IEnumSTATPROPSTG.Reset() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSTG.Reset(); } void IEnumSTATPROPSTG.Clone(out IEnumSTATPROPSTG ppenum) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG enumSTATPROPSTG; _unsafeEnumSTATPROPSTG.Clone(out enumSTATPROPSTG); if (enumSTATPROPSTG != null) ppenum = new SafeIEnumSTATPROPSTGImplementation(enumSTATPROPSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG _unsafeEnumSTATPROPSTG; } #endif private class SafeIEnumSTATSTGImplementation : IEnumSTATSTG, IDisposable { internal SafeIEnumSTATSTGImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG enumSTATSTG) { _unsafeEnumSTATSTG = enumSTATSTG; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeEnumSTATSTG != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeEnumSTATSTG); } } finally { _unsafeEnumSTATSTG = null; } } void IEnumSTATSTG.Next( UInt32 celt, out System.Runtime.InteropServices.ComTypes.STATSTG rgelt, // This should really be array, but we're OK if we stick with one item at a time. // Because marshalling an array of structs that have pointers to strings are troublesome. out UInt32 pceltFetched ) { SecurityHelper.DemandCompoundFileIOPermission(); if (celt != 1) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "celt", celt.ToString(CultureInfo.InvariantCulture))); } _unsafeEnumSTATSTG.Next( celt, out rgelt, out pceltFetched ); } void IEnumSTATSTG.Skip( UInt32 celt ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATSTG.Skip( celt ); } void IEnumSTATSTG.Reset() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATSTG.Reset(); } void IEnumSTATSTG.Clone( out IEnumSTATSTG ppenum ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG enumSTATSTG; _unsafeEnumSTATSTG.Clone( out enumSTATSTG ); if (enumSTATSTG != null) ppenum = new SafeIEnumSTATSTGImplementation(enumSTATSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG _unsafeEnumSTATSTG; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // The COM and P/Invoke interop code necessary for the managed compound // file layer to call the existing APIs in OLE32.DLL. // // Note that not everything is properly ported, for example the SNB type // used in several IStorage methods is just ignored. // // History: // 05/10/2002: RogerCh: Initial creation. // 07/31/2002: RogerCh: Add LockBytes support, suppress unmanaged code security. // 05/20/2003: RogerCh: Ported to WCP tree. // 05/28/2003: RogerCh: Removed name checks - now handled by LongNameManager // 02/10/2006: YoungGK: Separated the security suppressed interfaces and APIs // Created the wrapper class that calls unmanaged APIs // //----------------------------------------------------------------------------- using System; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.Windows; using MS.Internal.Interop; using MS.Internal.WindowsBase; // for SecurityHelper using CultureInfo = System.Globalization.CultureInfo; namespace MS.Internal.IO.Packaging.CompoundFile { //// Critical: This class serves as a wrapper on top of several unmanaged CompoundFile // interfaces and API calls. These interfaces and APIs has suppress unamanged // code attribute set. // It is up to this class to ensure that the only calls that can go through must // be either done in Full Trust or with CompoundFileIOPermission. // This class exposes several internal APIs and interfaces built on top of classes that // demand the CompoundFileIOPermission and then call through the matching member of // the unsafe APIs and interfaces. // SecurityTreatAsSafe: Demands CompoundFileIOPermission before it makes any calls to // unmanaged APIs // [SecurityCritical(SecurityCriticalScope.Everything), SecurityTreatAsSafe] internal static class SafeNativeCompoundFileMethods { ////// Utility function to update a grfMode value based on FileAccess. /// 6/12/2002: Fixes bug #4938, 4960, 5096, 4858 /// /// FileAccess we're translating /// Mode flag parameter to modify //// SecurityTreatAsSafe: Makes NO call to security suppressed unmanaged code // internal static void UpdateModeFlagFromFileAccess( FileAccess access, ref int grfMode ) { // Supporting write-only scenarios container-wide gets tricky and it // is rarely used. Don't support it for now because of poor // cost/benefit ratio. if( FileAccess.Write == access ) throw new NotSupportedException( SR.Get(SRID.WriteOnlyUnsupported)); // Generate STGM from FileAccess // STGM_READ is 0x00, so it's "by default" if( ( FileAccess.ReadWrite == (access & FileAccess.ReadWrite) ) || ( (FileAccess.Read | FileAccess.Write) == (access & (FileAccess.Read | FileAccess.Write))) ) { grfMode |= SafeNativeCompoundFileConstants.STGM_READWRITE; } else if( FileAccess.Write == (access & FileAccess.Write) ) { grfMode |= SafeNativeCompoundFileConstants.STGM_WRITE; } else if( FileAccess.Read != (access & FileAccess.Read)) { throw new ArgumentException( SR.Get(SRID.FileAccessInvalid)); } } internal static int SafeStgCreateDocfileOnStream( Stream s, int grfMode, out IStorage ppstgOpen ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(s != null, "s cannot be null"); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream lockByteStream = new UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream(s); int result; result = UnsafeNativeCompoundFileMethods.StgCreateDocfileOnILockBytes( (UnsafeNativeCompoundFileMethods.UnsafeNativeILockBytes) lockByteStream, grfMode, 0, // Must be zero out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppstgOpen = new SafeIStorageImplementation(storage, lockByteStream); else { ppstgOpen = null; lockByteStream.Dispose(); } return result; } internal static int SafeStgOpenStorageOnStream( Stream s, int grfMode, out IStorage ppstgOpen ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(s != null, "s cannot be null"); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream lockByteStream = new UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream(s); int result; result = UnsafeNativeCompoundFileMethods.StgOpenStorageOnILockBytes( (UnsafeNativeCompoundFileMethods.UnsafeNativeILockBytes) lockByteStream, null, grfMode, new IntPtr(0), // Pointer to SNB struct, not marshalled, must be null. 0, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppstgOpen = new SafeIStorageImplementation(storage); else { ppstgOpen = null; lockByteStream.Dispose(); } return result; } internal static int SafeStgCreateStorageEx( string pwcsName, //Pointer to path of compound file to create int grfMode, // Specifies the access mode for opening the storage object int stgfmt, // Specifies the storage file format, 5 is DocFile int grfAttrs, // Reserved; must be zero IntPtr pStgOptions,// Pointer to STGOPTIONS, not marshalled, must use NULL. IntPtr reserved2, // Reserved; must be null ref Guid riid, // Specifies the GUID of the interface pointer out IStorage ppObjectOpen //Pointer to an interface pointer ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = UnsafeNativeCompoundFileMethods.StgCreateStorageEx( pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, reserved2, ref riid, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppObjectOpen = new SafeIStorageImplementation(storage); else ppObjectOpen = null; return result; } internal static int SafeStgOpenStorageEx( string pwcsName, //Pointer to path of compound file to create int grfMode, // Specifies the access mode for opening the storage object int stgfmt, // Specifies the storage file format, 5 is DocFile int grfAttrs, // Reserved; must be zero IntPtr pStgOptions,// Pointer to STGOPTIONS, not marshalled, must use NULL. IntPtr reserved2, // Reserved; must be null ref Guid riid, // Specifies the GUID of the interface pointer out IStorage ppObjectOpen //Pointer to an interface pointer ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = UnsafeNativeCompoundFileMethods.StgOpenStorageEx( pwcsName, grfMode, stgfmt, grfAttrs, pStgOptions, reserved2, ref riid, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) ppObjectOpen = new SafeIStorageImplementation(storage); else ppObjectOpen = null; return result; } //// Critical: This method calls security suppressed unmanaged CompoundFile code. // ComoundFileIOPermission needs to be demanded to ensure that the only calls // that can go through must be either done in Full Trust or with under assertion of // CompoundFileIOPermission. // SecurityTreatAsSafe: Demands CompoundFileIOPermission before it makes any calls to // unmanaged APIs // internal static int SafePropVariantClear(ref PROPVARIANT pvar) { SecurityHelper.DemandCompoundFileIOPermission(); return UnsafeNativeCompoundFileMethods.PropVariantClear(ref pvar); } private class SafeIStorageImplementation : IStorage, IPropertySetStorage, IDisposable { internal SafeIStorageImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage) : this(storage, null) { } internal SafeIStorageImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage, UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream lockBytesStream) { SecurityHelper.DemandCompoundFileIOPermission(); if (storage == null) { throw new ArgumentNullException("storage"); } _unsafeStorage = storage; _unsafePropertySetStorage = (UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertySetStorage) _unsafeStorage; _unsafeLockByteStream = lockBytesStream; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeStorage != null)) { // We only need to release IStorage only not IPropertySetStorage // since it shares once instance of RCW MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeStorage); // If the storage was originally opened on lockbyte implementation // we need to dispose it as well if (_unsafeLockByteStream != null) { _unsafeLockByteStream.Dispose(); } } } finally { _unsafeStorage = null; _unsafePropertySetStorage = null; _unsafeLockByteStream = null; } } // // IStorage Implementation // int IStorage.CreateStream( string pwcsName, int grfMode, int reserved1, int reserved2, out IStream ppstm ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream; int result; result = _unsafeStorage.CreateStream( pwcsName, grfMode, reserved1, reserved2, out stream); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstm = new SafeIStreamImplementation(stream); } else { ppstm = null; } return result; } int IStorage.OpenStream( string pwcsName, int reserved1, int grfMode, int reserved2, out IStream ppstm ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream; int result; result = _unsafeStorage.OpenStream( pwcsName, reserved1, grfMode, reserved2, out stream); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstm = new SafeIStreamImplementation(stream); } else { ppstm = null; } return result; } int IStorage.CreateStorage( string pwcsName, int grfMode, int reserved1, int reserved2, out IStorage ppstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = _unsafeStorage.CreateStorage( pwcsName, grfMode, reserved1, reserved2, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstg = new SafeIStorageImplementation(storage); } else { ppstg = null; } return result; } int IStorage.OpenStorage( string pwcsName, IStorage pstgPriority, int grfMode, IntPtr snbExclude, // Not properly translated, but must be NULL anyway int reserved, out IStorage ppstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage storage; int result; result = _unsafeStorage.OpenStorage( pwcsName, pstgPriority == null ? null : ((SafeIStorageImplementation) pstgPriority)._unsafeStorage, grfMode, snbExclude, reserved, out storage); if (result == SafeNativeCompoundFileConstants.S_OK) { ppstg = new SafeIStorageImplementation(storage); } else { ppstg = null; } return result; } void IStorage.CopyTo( int ciidExclude, Guid[] rgiidExclude, IntPtr snbExclude, // Not properly translated, use NULL to avoid `blow-up IStorage ppstg ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(ppstg != null, "ppstg cannot be null"); _unsafeStorage.CopyTo( ciidExclude, rgiidExclude, snbExclude, ((SafeIStorageImplementation) ppstg)._unsafeStorage); } void IStorage.MoveElementTo( string pwcsName, IStorage pstgDest, string pwcsNewName, int grfFlags ) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(pstgDest != null, "pstgDest cannot be null"); _unsafeStorage.MoveElementTo( pwcsName, ((SafeIStorageImplementation) pstgDest)._unsafeStorage, pwcsNewName, grfFlags); } void IStorage.Commit( int grfCommitFlags ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.Commit( grfCommitFlags); } void IStorage.Revert() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.Revert(); } void IStorage.EnumElements( int reserved1, IntPtr reserved2, int reserved3, out IEnumSTATSTG ppEnum ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG enumSTATSTG; _unsafeStorage.EnumElements( reserved1, reserved2, reserved3, out enumSTATSTG); if (enumSTATSTG != null) ppEnum = new SafeIEnumSTATSTGImplementation(enumSTATSTG); else ppEnum = null; } void IStorage.DestroyElement( string pwcsName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.DestroyElement( pwcsName); } void IStorage.RenameElement( string pwcsOldName, string pwcsNewName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.RenameElement( pwcsOldName, pwcsNewName); } void IStorage.SetElementTimes( string pwcsName, System.Runtime.InteropServices.ComTypes.FILETIME pctime, System.Runtime.InteropServices.ComTypes.FILETIME patime, System.Runtime.InteropServices.ComTypes.FILETIME pmtime ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.SetElementTimes( pwcsName, pctime, patime, pmtime); } void IStorage.SetClass( ref Guid clsid ) // Hopefully "ref" is how I tell it to use a pointer { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.SetClass( ref clsid ); } void IStorage.SetStateBits( int grfStateBits, int grfMask ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.SetStateBits( grfStateBits, grfMask); } void IStorage.Stat( out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStorage.Stat( out pstatstg, grfStatFlag); } void IPropertySetStorage.Create( ref Guid rfmtid, ref Guid pclsid, UInt32 grfFlags, UInt32 grfMode, out IPropertyStorage ppprstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage propertyStorage; _unsafePropertySetStorage.Create( ref rfmtid, ref pclsid, grfFlags, grfMode, out propertyStorage ); if (propertyStorage != null) ppprstg = new SafeIPropertyStorageImplementation(propertyStorage); else ppprstg = null; } int IPropertySetStorage.Open( ref Guid rfmtid, UInt32 grfMode, out IPropertyStorage ppprstg ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage propertyStorage; int hr = _unsafePropertySetStorage.Open( ref rfmtid, grfMode, out propertyStorage ); if (propertyStorage != null) ppprstg = new SafeIPropertyStorageImplementation(propertyStorage); else ppprstg = null; return hr; } void IPropertySetStorage.Delete( ref Guid rfmtid ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertySetStorage.Delete( ref rfmtid ); } void IPropertySetStorage.Enum( out IEnumSTATPROPSETSTG ppenum ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG enumSTATPROPSETSTG; _unsafePropertySetStorage.Enum( out enumSTATPROPSETSTG ); if (enumSTATPROPSETSTG != null) ppenum = new SafeIEnumSTATPROPSETSTGImplementation(enumSTATPROPSETSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertySetStorage _unsafePropertySetStorage; private UnsafeNativeCompoundFileMethods.UnsafeNativeIStorage _unsafeStorage; private UnsafeNativeCompoundFileMethods.UnsafeLockBytesOnStream _unsafeLockByteStream; } private class SafeIStreamImplementation : IStream, IDisposable { internal SafeIStreamImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream) { _unsafeStream = stream; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeStream != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeStream); } } finally { _unsafeStream = null; } } // // IStream Implementation // void IStream.Read(Byte[] pv, int cb, out int pcbRead) { SecurityHelper.DemandCompoundFileIOPermission(); if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.Read(pv, cb, out pcbRead); } void IStream.Write(Byte[] pv, int cb, out int pcbWritten) { SecurityHelper.DemandCompoundFileIOPermission(); if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.Write(pv, cb, out pcbWritten); } // IStream portion void IStream.Seek(long dlibMove, int dwOrigin, out long plibNewPosition) { SecurityHelper.DemandCompoundFileIOPermission(); if (dwOrigin < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "dwOrigin", dwOrigin.ToString(CultureInfo.InvariantCulture))); } if (dlibMove < 0 && dwOrigin == SafeNativeCompoundFileConstants.STREAM_SEEK_SET) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "dlibMove", dlibMove.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.Seek(dlibMove, dwOrigin, out plibNewPosition); } void IStream.SetSize(long libNewSize) { SecurityHelper.DemandCompoundFileIOPermission(); if (libNewSize < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "libNewSize", libNewSize.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.SetSize(libNewSize); } void IStream.CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten) { SecurityHelper.DemandCompoundFileIOPermission(); Invariant.Assert(pstm != null, "pstm cannot be null"); if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.CopyTo(((SafeIStreamImplementation) pstm)._unsafeStream, cb, out pcbRead, out pcbWritten); } void IStream.Commit(int grfCommitFlags) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStream.Commit(grfCommitFlags); } void IStream.Revert() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStream.Revert(); } void IStream.LockRegion(long libOffset, long cb, int dwLockType) { SecurityHelper.DemandCompoundFileIOPermission(); if (libOffset < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "libOffset", libOffset.ToString(CultureInfo.InvariantCulture))); } if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.LockRegion(libOffset, cb, dwLockType); } void IStream.UnlockRegion(long libOffset, long cb, int dwLockType) { SecurityHelper.DemandCompoundFileIOPermission(); if (libOffset < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "libOffset", libOffset.ToString(CultureInfo.InvariantCulture))); } if (cb < 0) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "cb", cb.ToString(CultureInfo.InvariantCulture))); } _unsafeStream.UnlockRegion(libOffset, cb, dwLockType); } void IStream.Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeStream.Stat(out pstatstg, grfStatFlag); } void IStream.Clone(out IStream ppstm) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIStream stream; _unsafeStream.Clone(out stream); if (stream != null) { ppstm = new SafeIStreamImplementation(stream); } else { ppstm = null; } } private UnsafeNativeCompoundFileMethods.UnsafeNativeIStream _unsafeStream; } private class SafeIEnumSTATPROPSETSTGImplementation : IEnumSTATPROPSETSTG, IDisposable { internal SafeIEnumSTATPROPSETSTGImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG enumSTATPROPSETSTG) { _unsafeEnumSTATPROPSETSTG = enumSTATPROPSETSTG; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeEnumSTATPROPSETSTG != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeEnumSTATPROPSETSTG); } } finally { _unsafeEnumSTATPROPSETSTG = null; } } // // The caller must allocate an array of celt STATPROPSETSTG structures // to receive the results. // // This method is PreserveSig because it can return a non-0 success // code; S_FALSE => fewer than celt elements were returned. // int IEnumSTATPROPSETSTG.Next( UInt32 celt, STATPROPSETSTG rgelt, out UInt32 pceltFetched ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafeEnumSTATPROPSETSTG.Next( celt, rgelt, out pceltFetched ); } void IEnumSTATPROPSETSTG.Skip(UInt32 celt) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSETSTG.Skip(celt); } void IEnumSTATPROPSETSTG.Reset() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSETSTG.Reset(); } void IEnumSTATPROPSETSTG.Clone(out IEnumSTATPROPSETSTG ppenum) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG enumSTATPROPSETSTG; _unsafeEnumSTATPROPSETSTG.Clone(out enumSTATPROPSETSTG); if (enumSTATPROPSETSTG != null) ppenum = new SafeIEnumSTATPROPSETSTGImplementation(enumSTATPROPSETSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSETSTG _unsafeEnumSTATPROPSETSTG; } private class SafeIPropertyStorageImplementation : IPropertyStorage, IDisposable { internal SafeIPropertyStorageImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage propertyStorage) { _unsafePropertyStorage = propertyStorage; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafePropertyStorage != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafePropertyStorage); } } finally { _unsafePropertyStorage = null; } } // // We preserve the HRESULT on this method because we need to distinguish // between S_OK (we got the properties we asked for) and S_FALSE (none of // the properties exist). // int IPropertyStorage.ReadMultiple( UInt32 cpspec, PROPSPEC[] rgpspec, PROPVARIANT[] rgpropvar ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafePropertyStorage.ReadMultiple( cpspec, rgpspec, rgpropvar ); } void IPropertyStorage.WriteMultiple( UInt32 cpspec, PROPSPEC[] rgpspec, PROPVARIANT[] rgpropvar, uint propidNameFirst ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.WriteMultiple( cpspec, rgpspec, rgpropvar, propidNameFirst ); } void IPropertyStorage.DeleteMultiple( UInt32 cpspec, PROPSPEC[] rgpspec ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.DeleteMultiple( cpspec, rgpspec ); } void IPropertyStorage.ReadPropertyNames( UInt32 cpropid, UInt32[] rgpropid, string[] rglpwstrName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.ReadPropertyNames( cpropid, rgpropid, rglpwstrName ); } void IPropertyStorage.WritePropertyNames( UInt32 cpropid, UInt32[] rgpropid, string[] rglpwstrName ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.WritePropertyNames( cpropid, rgpropid, rglpwstrName ); } void IPropertyStorage.DeletePropertyNames( UInt32 cpropid, UInt32[] rgpropid ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.DeletePropertyNames( cpropid, rgpropid ); } void IPropertyStorage.Commit( UInt32 grfCommitFlags ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.Commit( grfCommitFlags ); } void IPropertyStorage.Revert() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.Revert(); } void IPropertyStorage.Enum( out IEnumSTATPROPSTG ppenum ) { SecurityHelper.DemandCompoundFileIOPermission(); #if Using_SafeIPropertyStorageImplementation_Enum UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG unsafeEnumSTATPROPSTG; _unsafePropertyStorage.Enum( out unsafeEnumSTATPROPSTG ); if (unsafeEnumSTATPROPSTG != null) ppenum = new SafeIEnumSTATPROPSTGImplementation(unsafeEnumSTATPROPSTG); else #endif ppenum = null; } void IPropertyStorage.SetTimes( ref System.Runtime.InteropServices.ComTypes.FILETIME pctime, ref System.Runtime.InteropServices.ComTypes.FILETIME patime, ref System.Runtime.InteropServices.ComTypes.FILETIME pmtime ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.SetTimes( ref pctime, ref patime, ref pmtime ); } void IPropertyStorage.SetClass( ref Guid clsid ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.SetClass( ref clsid ); } void IPropertyStorage.Stat( out STATPROPSETSTG pstatpsstg ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafePropertyStorage.Stat( out pstatpsstg ); } private UnsafeNativeCompoundFileMethods.UnsafeNativeIPropertyStorage _unsafePropertyStorage; } #if Using_SafeIPropertyStorageImplementation_Enum private class SafeIEnumSTATPROPSTGImplementation : IEnumSTATPROPSTG { internal SafeIEnumSTATPROPSTGImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG enumSTATPROPSTG) { _unsafeEnumSTATPROPSTG= enumSTATPROPSTG; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeEnumSTATPROPSTG != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeEnumSTATPROPSTG); } } finally { _unsafeEnumSTATPROPSTG = null; } } // // The caller must allocate an array of celt STATPROPSTG structures // to receive the results. // // This method is PreserveSig because it can return a non-0 success // code; S_FALSE => fewer than celt elements were returned. // int IEnumSTATPROPSTG.Next( UInt32 celt, STATPROPSTG rgelt, out UInt32 pceltFetched ) { SecurityHelper.DemandCompoundFileIOPermission(); return _unsafeEnumSTATPROPSTG.Next( celt, rgelt, out pceltFetched ); } void IEnumSTATPROPSTG.Skip(UInt32 celt) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSTG.Skip(celt); } void IEnumSTATPROPSTG.Reset() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATPROPSTG.Reset(); } void IEnumSTATPROPSTG.Clone(out IEnumSTATPROPSTG ppenum) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG enumSTATPROPSTG; _unsafeEnumSTATPROPSTG.Clone(out enumSTATPROPSTG); if (enumSTATPROPSTG != null) ppenum = new SafeIEnumSTATPROPSTGImplementation(enumSTATPROPSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATPROPSTG _unsafeEnumSTATPROPSTG; } #endif private class SafeIEnumSTATSTGImplementation : IEnumSTATSTG, IDisposable { internal SafeIEnumSTATSTGImplementation(UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG enumSTATSTG) { _unsafeEnumSTATSTG = enumSTATSTG; } public void Dispose() { SecurityHelper.DemandCompoundFileIOPermission(); Dispose(true); GC.SuppressFinalize(this); } ////// Dispose(bool) /// /// protected virtual void Dispose(bool disposing) { SecurityHelper.DemandCompoundFileIOPermission(); try { if (disposing && (_unsafeEnumSTATSTG != null)) { MS.Win32.UnsafeNativeMethods.SafeReleaseComObject((object) _unsafeEnumSTATSTG); } } finally { _unsafeEnumSTATSTG = null; } } void IEnumSTATSTG.Next( UInt32 celt, out System.Runtime.InteropServices.ComTypes.STATSTG rgelt, // This should really be array, but we're OK if we stick with one item at a time. // Because marshalling an array of structs that have pointers to strings are troublesome. out UInt32 pceltFetched ) { SecurityHelper.DemandCompoundFileIOPermission(); if (celt != 1) { throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "celt", celt.ToString(CultureInfo.InvariantCulture))); } _unsafeEnumSTATSTG.Next( celt, out rgelt, out pceltFetched ); } void IEnumSTATSTG.Skip( UInt32 celt ) { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATSTG.Skip( celt ); } void IEnumSTATSTG.Reset() { SecurityHelper.DemandCompoundFileIOPermission(); _unsafeEnumSTATSTG.Reset(); } void IEnumSTATSTG.Clone( out IEnumSTATSTG ppenum ) { SecurityHelper.DemandCompoundFileIOPermission(); UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG enumSTATSTG; _unsafeEnumSTATSTG.Clone( out enumSTATSTG ); if (enumSTATSTG != null) ppenum = new SafeIEnumSTATSTGImplementation(enumSTATSTG); else ppenum = null; } private UnsafeNativeCompoundFileMethods.UnsafeNativeIEnumSTATSTG _unsafeEnumSTATSTG; } } } // 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
- XamlTemplateSerializer.cs
- wgx_exports.cs
- TypeListConverter.cs
- DataServiceHost.cs
- SqlDataReader.cs
- DataGridViewTextBoxColumn.cs
- BrowserCapabilitiesCodeGenerator.cs
- PageContentCollection.cs
- LayoutTableCell.cs
- SafeNativeMethodsCLR.cs
- NetNamedPipeBindingCollectionElement.cs
- DWriteFactory.cs
- Int32KeyFrameCollection.cs
- InstanceNormalEvent.cs
- AutoGeneratedFieldProperties.cs
- WindowsScroll.cs
- DispatcherHookEventArgs.cs
- NetPeerTcpBindingCollectionElement.cs
- DataGridViewComboBoxEditingControl.cs
- ManagementException.cs
- VScrollProperties.cs
- SqlBuffer.cs
- RelatedEnd.cs
- ExpressionBuilder.cs
- SymLanguageType.cs
- IsolatedStorageFile.cs
- PagesSection.cs
- remotingproxy.cs
- DataGridrowEditEndingEventArgs.cs
- Registry.cs
- DataGridViewColumnEventArgs.cs
- MultipartContentParser.cs
- OrthographicCamera.cs
- MissingFieldException.cs
- Variable.cs
- DesignerTextWriter.cs
- TypeDescriptionProviderAttribute.cs
- Menu.cs
- OletxVolatileEnlistment.cs
- BitmapCodecInfoInternal.cs
- SafeFileHandle.cs
- ControlHelper.cs
- UnsignedPublishLicense.cs
- XmlUrlResolver.cs
- FolderBrowserDialogDesigner.cs
- TypeSystem.cs
- WindowsGraphics2.cs
- LogicalExpressionEditor.cs
- UpDownBase.cs
- PlatformNotSupportedException.cs
- SynchronizationHandlesCodeDomSerializer.cs
- FixUpCollection.cs
- ProfileGroupSettingsCollection.cs
- DeploymentExceptionMapper.cs
- KerberosReceiverSecurityToken.cs
- StorageTypeMapping.cs
- UIElementCollection.cs
- RemoteWebConfigurationHostServer.cs
- FreezableOperations.cs
- ListenerAdapter.cs
- TCEAdapterGenerator.cs
- OleStrCAMarshaler.cs
- GridItem.cs
- ToolStripItemTextRenderEventArgs.cs
- ChameleonKey.cs
- ColorPalette.cs
- AccessDataSource.cs
- TypeViewSchema.cs
- IdentitySection.cs
- CurrentChangingEventManager.cs
- QueryPageSettingsEventArgs.cs
- PreProcessInputEventArgs.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- PropertyTabAttribute.cs
- Type.cs
- DataContractSerializerServiceBehavior.cs
- PermissionSetTriple.cs
- DetailsViewCommandEventArgs.cs
- Animatable.cs
- FamilyMapCollection.cs
- ZipIOCentralDirectoryBlock.cs
- OneOfTypeConst.cs
- EventLogEntryCollection.cs
- XmlWriter.cs
- GridViewUpdatedEventArgs.cs
- PrtCap_Base.cs
- PropertyMapper.cs
- PersonalizationProviderHelper.cs
- CannotUnloadAppDomainException.cs
- SafeNativeMethods.cs
- NavigateEvent.cs
- StyleHelper.cs
- FixedSOMContainer.cs
- CqlErrorHelper.cs
- DesignerContextDescriptor.cs
- _FtpControlStream.cs
- GeometryDrawing.cs
- XmlByteStreamWriter.cs
- Point3DAnimationBase.cs
- ModelFactory.cs