PrivateUnsafeNativeCompoundFileMethods.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / MS / Internal / IO / Packaging / CompoundFile / PrivateUnsafeNativeCompoundFileMethods.cs / 1 / 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: YoungGK: 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: YoungGK: 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 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: YoungGK: 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: YoungGK: 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 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