PrivateUnsafeNativeCompoundFileMethods.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Packaging / CompoundFile / PrivateUnsafeNativeCompoundFileMethods.cs / 1305600 / PrivateUnsafeNativeCompoundFileMethods.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.
//
//  WARNING: This class should ONLY be access by SafeNativeCompoundFileMethods class 
//      although this class is marked as "internal". This is only done because
//      TAS cannot be set on the individual member level if the entire class is 
//      marked as SecurityCritical. This class should be treated as if it is a nested 
//      private class of SafeNativeCompoundfileMethods.
// 
// History:
//  02/01/2006: [....]: Seperated from NativeCompoundFileAPIs.cs
//                  This file holds all unsafe APIs and interfaces
//      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: [....]: Added the security suppressed CF interfaces and APIs
// 
//-----------------------------------------------------------------------------

using System;
using System.IO; 
using System.Runtime.InteropServices;
using System.Windows; 
 
using MS.Internal.Interop;    // For PROPSPEC and PROPVARIANT.
using System.Security; 
using MS.Internal.WindowsBase;

using CultureInfo = System.Globalization.CultureInfo;
 
namespace MS.Internal.IO.Packaging.CompoundFile
{ 
    //  
    //     Critical:  These interfaces and APIs have suppress unamanged code attribute set.
    //     It is up to the wrapper class (SafeNativeCompoundFileMethods) to ensure that the only 
    //     calls that can go through must be either done in Full Trust or with CompoundFileIOPermission.
    // 
    [SecurityCritical(SecurityCriticalScope.Everything)]
    internal static class UnsafeNativeCompoundFileMethods 
    {
        ///////////////////////////////////////////////////// 
        // Security Suppressed APIs 
        /////////////////////////////////////////////////////
 
        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity]
        internal static extern int StgCreateDocfileOnILockBytes(
            UnsafeNativeILockBytes plkbyt, 
            int grfMode,
            int reserved, // Must be zero 
            out UnsafeNativeIStorage ppstgOpen 
            );
 
        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity]
        internal static extern int StgOpenStorageOnILockBytes(
            UnsafeNativeILockBytes plkbyt, 
            UnsafeNativeIStorage pStgPriority, // Most often NULL
            int grfMode, 
            IntPtr snbExclude, // Pointer to SNB struct, not marshalled, must be null. 
            int reserved, // Must be zero
            out UnsafeNativeIStorage ppstgOpen 
            );

        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity] 
        internal static extern int StgCreateStorageEx(
            [In, MarshalAs( UnmanagedType.LPWStr )] 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 UnsafeNativeIStorage ppObjectOpen       //Pointer to an interface pointer 
            );
 
        [DllImport("ole32.dll")] 
        [SuppressUnmanagedCodeSecurity]
        internal static extern int StgOpenStorageEx( 
            [In, MarshalAs( UnmanagedType.LPWStr )] 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 UnsafeNativeIStorage ppObjectOpen       //Pointer to an interface pointer
            ); 

        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity]
        internal static extern int PropVariantClear(ref PROPVARIANT pvar); 

        internal class UnsafeLockBytesOnStream : UnsafeNativeILockBytes, IDisposable 
        { 
            internal UnsafeLockBytesOnStream( Stream underlyingStream )
            { 
                if( !underlyingStream.CanSeek )
                {
                    throw new NotSupportedException(
                        SR.Get(SRID.ILockBytesStreamMustSeek)); 
                }
 
                _baseStream = underlyingStream; 
            }
 
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this); 
            }
 
            ///  
            /// Dispose(bool)
            ///  
            /// 
            protected virtual void Dispose(bool disposing)
            {
                if (disposing && (_baseStream != null)) 
                {
                    // We only set the _baseStream to null without closing it, 
                    // because _baseStream is a reference of an outside stream, 
                    // and was set when this class was constructed. We didn't open
                    // the stream and should leave the original owner of the stream 
                    // to close it.
                    _baseStream = null;
                }
            } 

            private void CheckDisposed() 
            { 
                if (_baseStream==null)
                { 
                    throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed));
                }
            }
 
            void UnsafeNativeILockBytes.ReadAt (
                UInt64 offset, 
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] Byte[] pv, 
                int cb,
                out int pcbRead) 
            {
                CheckDisposed();
                checked { _baseStream.Seek( (long)offset, SeekOrigin.Begin ); }
                pcbRead = _baseStream.Read( pv, 0, cb ); 
            }
 
            void UnsafeNativeILockBytes.WriteAt( 
                UInt64 offset,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Byte[] pv, 
                int cb,
                out int pcbWritten)
            {
                CheckDisposed(); 
                checked { _baseStream.Seek( (long)offset, SeekOrigin.Begin ); }
                _baseStream.Write( pv, 0, cb ); 
 
                // System.IO.Stream.Write does not return the number of bytes
                //  written.  Presumably this means an exception will be thrown 
                //  if fewer than cb bytes are written.
                pcbWritten = cb;
            }
 

            void UnsafeNativeILockBytes.Flush() 
            { 
                CheckDisposed();
                _baseStream.Flush(); 
            }


            void UnsafeNativeILockBytes.SetSize( UInt64 cb ) 
            {
                CheckDisposed(); 
                checked { _baseStream.SetLength((long)cb); } 
            }
 
            void UnsafeNativeILockBytes.LockRegion(
                UInt64 libOffset,
                UInt64 cb,
                int dwLockType ) 
            {
                throw new NotSupportedException(); 
            } 

 
            void UnsafeNativeILockBytes.UnlockRegion(
                UInt64 libOffset,
                UInt64 cb,
                int dwLockType ) 
            {
                throw new NotSupportedException(); 
            } 

 
            void UnsafeNativeILockBytes.Stat(
                out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                int grfStatFlag )
            { 
                CheckDisposed();
 
                if ((grfStatFlag & ~(SafeNativeCompoundFileConstants.STATFLAG_NONAME | 
                                     SafeNativeCompoundFileConstants.STATFLAG_NOOPEN  )) != 0)
                { 
                    // validate grfStatFlag's value
                    throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "grfStatFlag", grfStatFlag.ToString(CultureInfo.InvariantCulture)));
                }
 
                System.Runtime.InteropServices.ComTypes.STATSTG returnValue = new System.Runtime.InteropServices.ComTypes.STATSTG();
 
                returnValue.grfLocksSupported = 0 ; // No lock supported 

                returnValue.cbSize = _baseStream.Length; 
                returnValue.type = SafeNativeCompoundFileConstants.STGTY_LOCKBYTES;

                pstatstg = returnValue;
            } 

            private Stream _baseStream; 
        } 

        ///////////////////////////////////////////////////// 
        // Security Suppressed Private Interfaces
        /////////////////////////////////////////////////////

        [Guid("0000000a-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport] 
        internal interface UnsafeNativeILockBytes 
        {
            void ReadAt ( 
                UInt64 offset,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] Byte[] pv,
                int cb,
                out int pcbRead); 
            void WriteAt(
                UInt64 offset, 
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Byte[] pv, 
                int cb,
                out int pcbWritten); 
            void Flush();
            void SetSize( UInt64 cb );
            void LockRegion(
                UInt64 libOffset, 
                UInt64 cb,
                int dwLockType ); 
            void UnlockRegion( 
                UInt64 libOffset,
                UInt64 cb, 
                int dwLockType );
            void Stat(
                out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                int grfStatFlag ); 
        }
 
        // Partial interface definition for existing IStorage 
        [Guid("0000000b-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIStorage
        { 
            [PreserveSig]
            int CreateStream( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName, 
                int grfMode,
                int reserved1, 
                int reserved2,
                out UnsafeNativeIStream ppstm );
            [PreserveSig]
            int OpenStream( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName,
                int reserved1, 
                int grfMode, 
                int reserved2,
                out UnsafeNativeIStream ppstm ); 
            [PreserveSig]
            int CreateStorage(
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName,
                int grfMode, 
                int reserved1,
                int reserved2, 
                out UnsafeNativeIStorage ppstg ); 
            [PreserveSig]
            int OpenStorage( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName,
                UnsafeNativeIStorage pstgPriority,
                int grfMode,
                IntPtr snbExclude,// Not properly translated, must be NULL anyway 
                int reserved,
                out UnsafeNativeIStorage ppstg ); 
            void CopyTo( 
                int ciidExclude,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgiidExclude, 
                IntPtr snbExclude,// Not properly translated, use NULL to avoid `blow-up
                UnsafeNativeIStorage ppstg );
            void MoveElementTo(
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName, 
                UnsafeNativeIStorage pstgDest,
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsNewName, 
                int grfFlags ); 
            void Commit(
                int grfCommitFlags ); 
            void Revert();
            void EnumElements(
                int reserved1,
                IntPtr reserved2, 
                int reserved3,
                out UnsafeNativeIEnumSTATSTG ppEnum ); 
            void DestroyElement( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName );
            void RenameElement( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsOldName,
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsNewName );
            void SetElementTimes(
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName, 
                System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                System.Runtime.InteropServices.ComTypes.FILETIME patime, 
                System.Runtime.InteropServices.ComTypes.FILETIME pmtime ); 
            void SetClass(
                ref Guid clsid ); // Hopefully "ref" is how I tell it to use a pointer 
            void SetStateBits(
                int grfStateBits,
                int grfMask );
            void Stat( 
                out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                int grfStatFlag ); 
        } 

        [Guid("0000000c-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIStream 
        {
            // ISequentialStream portion 
            void Read([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte[] pv, int cb, out int pcbRead); 
            void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Byte[] pv, int cb, out int pcbWritten);
 
            // IStream portion
            void Seek(long dlibMove, int dwOrigin, out long plibNewPosition);
            void SetSize(long libNewSize);
            void CopyTo(UnsafeNativeIStream pstm, long cb, out long pcbRead, out long pcbWritten); 
            void Commit(int grfCommitFlags);
            void Revert(); 
            void LockRegion(long libOffset, long cb, int dwLockType); 
            void UnlockRegion(long libOffset, long cb, int dwLockType);
            void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag); 
            void Clone(out UnsafeNativeIStream ppstm);
        }

        [ComImport] 
        [Guid("0000013A-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
        [SuppressUnmanagedCodeSecurity] 
        internal interface UnsafeNativeIPropertySetStorage
        { 
            void Create(
                    ref Guid rfmtid,
                    ref Guid pclsid,
                    UInt32 grfFlags, 
                    UInt32 grfMode,
                    out UnsafeNativeIPropertyStorage ppprstg 
                    ); 

            [PreserveSig] 
            int Open(
                    ref Guid rfmtid,
                    UInt32 grfMode,
                    out UnsafeNativeIPropertyStorage ppprstg 
                    );
 
            void Delete( 
                    ref Guid rfmtid
                    ); 

            void Enum(
                    out UnsafeNativeIEnumSTATPROPSETSTG ppenum
                    ); 
        }
 
        [ComImport] 
        [Guid("0000013B-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIEnumSTATPROPSETSTG
        {
            // 
            // 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. 
            //
            [PreserveSig]
            int
            Next( 
                UInt32 celt,
                [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                STATPROPSETSTG rgelt, 
                out UInt32 pceltFetched
                ); 

            void Skip(UInt32 celt);

            void Reset(); 

            void Clone(out UnsafeNativeIEnumSTATPROPSETSTG ppenum); 
        } 

        [ComImport] 
        [Guid("00000138-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIPropertyStorage 
        {
            // 
            // 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). 
            //
            [PreserveSig]
            int
            ReadMultiple( 
                UInt32 cpspec,
                [In,  MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                PROPSPEC[] rgpspec, 
                [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                PROPVARIANT[] rgpropvar 
                );

            void WriteMultiple(
                UInt32 cpspec, 
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                PROPSPEC[] rgpspec, 
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                PROPVARIANT[] rgpropvar,
                uint propidNameFirst 
                );

            void DeleteMultiple(
                UInt32 cpspec, 
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                PROPSPEC[] rgpspec 
                ); 

            void ReadPropertyNames( 
                UInt32 cpropid,
                [In,  MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                UInt32[] rgpropid,
                [Out, MarshalAs(UnmanagedType.LPArray, 
                                ArraySubType=UnmanagedType.LPWStr,
                                SizeParamIndex=0)] 
                string[] rglpwstrName 
                );
 
            void WritePropertyNames(
                UInt32 cpropid,
                [In,  MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                UInt32[] rgpropid, 
                [In,  MarshalAs(UnmanagedType.LPArray,
                                ArraySubType=UnmanagedType.LPWStr, 
                                SizeParamIndex=0)] 
                string[] rglpwstrName
                ); 

            void DeletePropertyNames(
                UInt32 cpropid,
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                UInt32[] rgpropid
                ); 
 
            void Commit(
                UInt32 grfCommitFlags 
                );

            void Revert();
 
            void Enum(
                out UnsafeNativeIEnumSTATPROPSTG ppenum 
                ); 

            void SetTimes( 
                ref System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                ref System.Runtime.InteropServices.ComTypes.FILETIME patime,
                ref System.Runtime.InteropServices.ComTypes.FILETIME pmtime
                ); 

            void SetClass( 
                ref Guid clsid 
                );
 
            void Stat(
                out STATPROPSETSTG pstatpsstg
                );
        } 

        [ComImport] 
        [Guid("00000139-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [SuppressUnmanagedCodeSecurity] 
        internal interface UnsafeNativeIEnumSTATPROPSTG
            {
                //
                // 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.
                // 
            [PreserveSig]
                int
            Next(
                    UInt32 celt, 
                    [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                    STATPROPSTG rgelt, 
                    out UInt32 pceltFetched 
                    );
 
            void Skip(UInt32 celt);

            void Reset();
 
            void Clone(out UnsafeNativeIEnumSTATPROPSTG ppenum);
        } 
 

        [Guid("0000000d-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIEnumSTATSTG 
        {
            void 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 );
            void Skip(
                UInt32 celt );
            void Reset(); 
            void Clone(
                out UnsafeNativeIEnumSTATSTG ppenum ); 
        } 
    }
} 

// 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.
//
//  WARNING: This class should ONLY be access by SafeNativeCompoundFileMethods class 
//      although this class is marked as "internal". This is only done because
//      TAS cannot be set on the individual member level if the entire class is 
//      marked as SecurityCritical. This class should be treated as if it is a nested 
//      private class of SafeNativeCompoundfileMethods.
// 
// History:
//  02/01/2006: [....]: Seperated from NativeCompoundFileAPIs.cs
//                  This file holds all unsafe APIs and interfaces
//      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: [....]: Added the security suppressed CF interfaces and APIs
// 
//-----------------------------------------------------------------------------

using System;
using System.IO; 
using System.Runtime.InteropServices;
using System.Windows; 
 
using MS.Internal.Interop;    // For PROPSPEC and PROPVARIANT.
using System.Security; 
using MS.Internal.WindowsBase;

using CultureInfo = System.Globalization.CultureInfo;
 
namespace MS.Internal.IO.Packaging.CompoundFile
{ 
    //  
    //     Critical:  These interfaces and APIs have suppress unamanged code attribute set.
    //     It is up to the wrapper class (SafeNativeCompoundFileMethods) to ensure that the only 
    //     calls that can go through must be either done in Full Trust or with CompoundFileIOPermission.
    // 
    [SecurityCritical(SecurityCriticalScope.Everything)]
    internal static class UnsafeNativeCompoundFileMethods 
    {
        ///////////////////////////////////////////////////// 
        // Security Suppressed APIs 
        /////////////////////////////////////////////////////
 
        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity]
        internal static extern int StgCreateDocfileOnILockBytes(
            UnsafeNativeILockBytes plkbyt, 
            int grfMode,
            int reserved, // Must be zero 
            out UnsafeNativeIStorage ppstgOpen 
            );
 
        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity]
        internal static extern int StgOpenStorageOnILockBytes(
            UnsafeNativeILockBytes plkbyt, 
            UnsafeNativeIStorage pStgPriority, // Most often NULL
            int grfMode, 
            IntPtr snbExclude, // Pointer to SNB struct, not marshalled, must be null. 
            int reserved, // Must be zero
            out UnsafeNativeIStorage ppstgOpen 
            );

        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity] 
        internal static extern int StgCreateStorageEx(
            [In, MarshalAs( UnmanagedType.LPWStr )] 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 UnsafeNativeIStorage ppObjectOpen       //Pointer to an interface pointer 
            );
 
        [DllImport("ole32.dll")] 
        [SuppressUnmanagedCodeSecurity]
        internal static extern int StgOpenStorageEx( 
            [In, MarshalAs( UnmanagedType.LPWStr )] 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 UnsafeNativeIStorage ppObjectOpen       //Pointer to an interface pointer
            ); 

        [DllImport("ole32.dll")]
        [SuppressUnmanagedCodeSecurity]
        internal static extern int PropVariantClear(ref PROPVARIANT pvar); 

        internal class UnsafeLockBytesOnStream : UnsafeNativeILockBytes, IDisposable 
        { 
            internal UnsafeLockBytesOnStream( Stream underlyingStream )
            { 
                if( !underlyingStream.CanSeek )
                {
                    throw new NotSupportedException(
                        SR.Get(SRID.ILockBytesStreamMustSeek)); 
                }
 
                _baseStream = underlyingStream; 
            }
 
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this); 
            }
 
            ///  
            /// Dispose(bool)
            ///  
            /// 
            protected virtual void Dispose(bool disposing)
            {
                if (disposing && (_baseStream != null)) 
                {
                    // We only set the _baseStream to null without closing it, 
                    // because _baseStream is a reference of an outside stream, 
                    // and was set when this class was constructed. We didn't open
                    // the stream and should leave the original owner of the stream 
                    // to close it.
                    _baseStream = null;
                }
            } 

            private void CheckDisposed() 
            { 
                if (_baseStream==null)
                { 
                    throw new ObjectDisposedException(null, SR.Get(SRID.StreamObjectDisposed));
                }
            }
 
            void UnsafeNativeILockBytes.ReadAt (
                UInt64 offset, 
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] Byte[] pv, 
                int cb,
                out int pcbRead) 
            {
                CheckDisposed();
                checked { _baseStream.Seek( (long)offset, SeekOrigin.Begin ); }
                pcbRead = _baseStream.Read( pv, 0, cb ); 
            }
 
            void UnsafeNativeILockBytes.WriteAt( 
                UInt64 offset,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Byte[] pv, 
                int cb,
                out int pcbWritten)
            {
                CheckDisposed(); 
                checked { _baseStream.Seek( (long)offset, SeekOrigin.Begin ); }
                _baseStream.Write( pv, 0, cb ); 
 
                // System.IO.Stream.Write does not return the number of bytes
                //  written.  Presumably this means an exception will be thrown 
                //  if fewer than cb bytes are written.
                pcbWritten = cb;
            }
 

            void UnsafeNativeILockBytes.Flush() 
            { 
                CheckDisposed();
                _baseStream.Flush(); 
            }


            void UnsafeNativeILockBytes.SetSize( UInt64 cb ) 
            {
                CheckDisposed(); 
                checked { _baseStream.SetLength((long)cb); } 
            }
 
            void UnsafeNativeILockBytes.LockRegion(
                UInt64 libOffset,
                UInt64 cb,
                int dwLockType ) 
            {
                throw new NotSupportedException(); 
            } 

 
            void UnsafeNativeILockBytes.UnlockRegion(
                UInt64 libOffset,
                UInt64 cb,
                int dwLockType ) 
            {
                throw new NotSupportedException(); 
            } 

 
            void UnsafeNativeILockBytes.Stat(
                out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                int grfStatFlag )
            { 
                CheckDisposed();
 
                if ((grfStatFlag & ~(SafeNativeCompoundFileConstants.STATFLAG_NONAME | 
                                     SafeNativeCompoundFileConstants.STATFLAG_NOOPEN  )) != 0)
                { 
                    // validate grfStatFlag's value
                    throw new ArgumentException(SR.Get(SRID.InvalidArgumentValue, "grfStatFlag", grfStatFlag.ToString(CultureInfo.InvariantCulture)));
                }
 
                System.Runtime.InteropServices.ComTypes.STATSTG returnValue = new System.Runtime.InteropServices.ComTypes.STATSTG();
 
                returnValue.grfLocksSupported = 0 ; // No lock supported 

                returnValue.cbSize = _baseStream.Length; 
                returnValue.type = SafeNativeCompoundFileConstants.STGTY_LOCKBYTES;

                pstatstg = returnValue;
            } 

            private Stream _baseStream; 
        } 

        ///////////////////////////////////////////////////// 
        // Security Suppressed Private Interfaces
        /////////////////////////////////////////////////////

        [Guid("0000000a-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport] 
        internal interface UnsafeNativeILockBytes 
        {
            void ReadAt ( 
                UInt64 offset,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] Byte[] pv,
                int cb,
                out int pcbRead); 
            void WriteAt(
                UInt64 offset, 
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Byte[] pv, 
                int cb,
                out int pcbWritten); 
            void Flush();
            void SetSize( UInt64 cb );
            void LockRegion(
                UInt64 libOffset, 
                UInt64 cb,
                int dwLockType ); 
            void UnlockRegion( 
                UInt64 libOffset,
                UInt64 cb, 
                int dwLockType );
            void Stat(
                out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                int grfStatFlag ); 
        }
 
        // Partial interface definition for existing IStorage 
        [Guid("0000000b-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIStorage
        { 
            [PreserveSig]
            int CreateStream( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName, 
                int grfMode,
                int reserved1, 
                int reserved2,
                out UnsafeNativeIStream ppstm );
            [PreserveSig]
            int OpenStream( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName,
                int reserved1, 
                int grfMode, 
                int reserved2,
                out UnsafeNativeIStream ppstm ); 
            [PreserveSig]
            int CreateStorage(
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName,
                int grfMode, 
                int reserved1,
                int reserved2, 
                out UnsafeNativeIStorage ppstg ); 
            [PreserveSig]
            int OpenStorage( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName,
                UnsafeNativeIStorage pstgPriority,
                int grfMode,
                IntPtr snbExclude,// Not properly translated, must be NULL anyway 
                int reserved,
                out UnsafeNativeIStorage ppstg ); 
            void CopyTo( 
                int ciidExclude,
                [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgiidExclude, 
                IntPtr snbExclude,// Not properly translated, use NULL to avoid `blow-up
                UnsafeNativeIStorage ppstg );
            void MoveElementTo(
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName, 
                UnsafeNativeIStorage pstgDest,
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsNewName, 
                int grfFlags ); 
            void Commit(
                int grfCommitFlags ); 
            void Revert();
            void EnumElements(
                int reserved1,
                IntPtr reserved2, 
                int reserved3,
                out UnsafeNativeIEnumSTATSTG ppEnum ); 
            void DestroyElement( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName );
            void RenameElement( 
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsOldName,
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsNewName );
            void SetElementTimes(
                [In, MarshalAs( UnmanagedType.LPWStr )] string pwcsName, 
                System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                System.Runtime.InteropServices.ComTypes.FILETIME patime, 
                System.Runtime.InteropServices.ComTypes.FILETIME pmtime ); 
            void SetClass(
                ref Guid clsid ); // Hopefully "ref" is how I tell it to use a pointer 
            void SetStateBits(
                int grfStateBits,
                int grfMask );
            void Stat( 
                out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                int grfStatFlag ); 
        } 

        [Guid("0000000c-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIStream 
        {
            // ISequentialStream portion 
            void Read([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] Byte[] pv, int cb, out int pcbRead); 
            void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Byte[] pv, int cb, out int pcbWritten);
 
            // IStream portion
            void Seek(long dlibMove, int dwOrigin, out long plibNewPosition);
            void SetSize(long libNewSize);
            void CopyTo(UnsafeNativeIStream pstm, long cb, out long pcbRead, out long pcbWritten); 
            void Commit(int grfCommitFlags);
            void Revert(); 
            void LockRegion(long libOffset, long cb, int dwLockType); 
            void UnlockRegion(long libOffset, long cb, int dwLockType);
            void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag); 
            void Clone(out UnsafeNativeIStream ppstm);
        }

        [ComImport] 
        [Guid("0000013A-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
        [SuppressUnmanagedCodeSecurity] 
        internal interface UnsafeNativeIPropertySetStorage
        { 
            void Create(
                    ref Guid rfmtid,
                    ref Guid pclsid,
                    UInt32 grfFlags, 
                    UInt32 grfMode,
                    out UnsafeNativeIPropertyStorage ppprstg 
                    ); 

            [PreserveSig] 
            int Open(
                    ref Guid rfmtid,
                    UInt32 grfMode,
                    out UnsafeNativeIPropertyStorage ppprstg 
                    );
 
            void Delete( 
                    ref Guid rfmtid
                    ); 

            void Enum(
                    out UnsafeNativeIEnumSTATPROPSETSTG ppenum
                    ); 
        }
 
        [ComImport] 
        [Guid("0000013B-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIEnumSTATPROPSETSTG
        {
            // 
            // 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. 
            //
            [PreserveSig]
            int
            Next( 
                UInt32 celt,
                [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                STATPROPSETSTG rgelt, 
                out UInt32 pceltFetched
                ); 

            void Skip(UInt32 celt);

            void Reset(); 

            void Clone(out UnsafeNativeIEnumSTATPROPSETSTG ppenum); 
        } 

        [ComImport] 
        [Guid("00000138-0000-0000-C000-000000000046")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIPropertyStorage 
        {
            // 
            // 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). 
            //
            [PreserveSig]
            int
            ReadMultiple( 
                UInt32 cpspec,
                [In,  MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                PROPSPEC[] rgpspec, 
                [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                PROPVARIANT[] rgpropvar 
                );

            void WriteMultiple(
                UInt32 cpspec, 
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                PROPSPEC[] rgpspec, 
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                PROPVARIANT[] rgpropvar,
                uint propidNameFirst 
                );

            void DeleteMultiple(
                UInt32 cpspec, 
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                PROPSPEC[] rgpspec 
                ); 

            void ReadPropertyNames( 
                UInt32 cpropid,
                [In,  MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                UInt32[] rgpropid,
                [Out, MarshalAs(UnmanagedType.LPArray, 
                                ArraySubType=UnmanagedType.LPWStr,
                                SizeParamIndex=0)] 
                string[] rglpwstrName 
                );
 
            void WritePropertyNames(
                UInt32 cpropid,
                [In,  MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                UInt32[] rgpropid, 
                [In,  MarshalAs(UnmanagedType.LPArray,
                                ArraySubType=UnmanagedType.LPWStr, 
                                SizeParamIndex=0)] 
                string[] rglpwstrName
                ); 

            void DeletePropertyNames(
                UInt32 cpropid,
                [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] 
                UInt32[] rgpropid
                ); 
 
            void Commit(
                UInt32 grfCommitFlags 
                );

            void Revert();
 
            void Enum(
                out UnsafeNativeIEnumSTATPROPSTG ppenum 
                ); 

            void SetTimes( 
                ref System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                ref System.Runtime.InteropServices.ComTypes.FILETIME patime,
                ref System.Runtime.InteropServices.ComTypes.FILETIME pmtime
                ); 

            void SetClass( 
                ref Guid clsid 
                );
 
            void Stat(
                out STATPROPSETSTG pstatpsstg
                );
        } 

        [ComImport] 
        [Guid("00000139-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [SuppressUnmanagedCodeSecurity] 
        internal interface UnsafeNativeIEnumSTATPROPSTG
            {
                //
                // 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.
                // 
            [PreserveSig]
                int
            Next(
                    UInt32 celt, 
                    [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)]
                    STATPROPSTG rgelt, 
                    out UInt32 pceltFetched 
                    );
 
            void Skip(UInt32 celt);

            void Reset();
 
            void Clone(out UnsafeNativeIEnumSTATPROPSTG ppenum);
        } 
 

        [Guid("0000000d-0000-0000-C000-000000000046")] 
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        [ComImport]
        [SuppressUnmanagedCodeSecurity]
        internal interface UnsafeNativeIEnumSTATSTG 
        {
            void 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 );
            void Skip(
                UInt32 celt );
            void Reset(); 
            void Clone(
                out UnsafeNativeIEnumSTATSTG ppenum ); 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK