﻿/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied. 
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 * 
 * Author							Change						Date
 *******************************************************************************
 * Jan Källman		Added		01-01-2012
 * Jan Källman      Added compression support 27-03-2012
 *******************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using comTypes = System.Runtime.InteropServices.ComTypes;
using System.IO;
using System.Security;

namespace OfficeOpenXml.Utils
{
#if !MONO
    internal class CompoundDocument
    {        
        internal class StoragePart
        {
            public StoragePart()
            {

            }
            internal Dictionary<string, StoragePart> SubStorage = new Dictionary<string, StoragePart>();
            internal Dictionary<string, byte[]> DataStreams = new Dictionary<string, byte[]>();
        }
        internal StoragePart Storage = null;
        internal CompoundDocument()
        {
            Storage = new CompoundDocument.StoragePart();
        }
        internal CompoundDocument(FileInfo fi)
        {
            Read(fi);
        }
        internal CompoundDocument(ILockBytes lb)
        {
            Read(lb);
        }
        internal CompoundDocument(byte[] doc)
        {
            Read(doc);
        }
        internal void Read(FileInfo fi)
        {
            var b = File.ReadAllBytes(fi.FullName);
            Read(b);
        }
        [SecuritySafeCritical]
        internal void Read(byte[] doc)
        {
            ILockBytes lb;
            var iret = CreateILockBytesOnHGlobal(IntPtr.Zero, true, out lb);

            IntPtr buffer = Marshal.AllocHGlobal(doc.Length);
            Marshal.Copy(doc, 0, buffer, doc.Length);
            UIntPtr readSize;
            lb.WriteAt(0, buffer, doc.Length, out readSize);
            Marshal.FreeHGlobal(buffer);

            Read(lb);
        }

        [SecuritySafeCritical]
        internal void Read(ILockBytes lb)
        {
            if (StgIsStorageILockBytes(lb) == 0)
            {
                IStorage storage = null;
                if (StgOpenStorageOnILockBytes(
                    lb,
                    null,
                    STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE,
                    IntPtr.Zero,
                    0,
                    out storage) == 0)
                {
                    Storage = new StoragePart();
                    ReadParts(storage, Storage);
                    Marshal.ReleaseComObject(storage);
                }
            }
            else
            {
                throw (new InvalidDataException(string.Format("Part is not a compound document")));
            }
        }
        #region  Compression
        /// <summary>
        /// Compression using a run length encoding algorithm.
        /// See MS-OVBA Section 2.4
        /// </summary>
        /// <param name="part">Byte array to decompress</param>
        /// <returns></returns>
        internal static byte[] CompressPart(byte[] part)
        {
            MemoryStream ms = new MemoryStream(4096);
            BinaryWriter br = new BinaryWriter(ms);
            br.Write((byte)1);

            int compStart = 1;
            int compEnd = 4098;
            int decompStart = 0;
            int decompEnd = part.Length < 4096 ? part.Length : 4096;

            while (decompStart < decompEnd && compStart < compEnd)
            {
                byte[] chunk = CompressChunk(part, ref decompStart);
                ushort header;
                if (chunk == null || chunk.Length == 0)
                {
                    header = 4096 | 0x600;  //B=011 A=0
                }
                else
                {
                    header = (ushort)(((chunk.Length - 1) & 0xFFF));
                    header |= 0xB000;   //B=011 A=1
                    br.Write(header);
                    br.Write(chunk);                    
                }
                decompEnd = part.Length < decompStart + 4096 ? part.Length : decompStart+4096;
            }

            
            br.Flush();
            return ms.ToArray();        
        }
        private static byte[] CompressChunk(byte[] buffer, ref int startPos)
        {
            var comprBuffer=new byte[4096];
            int flagPos = 0;
            int cPos=1;
            int dPos = startPos;
            int dEnd=startPos+4096 < buffer.Length? startPos+4096 : buffer.Length;
            while(dPos<dEnd)
            {
                byte tokenFlags = 0;
                for (int i = 0; i < 8; i++)
                {
                    if (dPos - startPos > 0)
                    {
                        int bestCandidate = -1;
                        int bestLength = 0;
                        int candidate = dPos - 1;
                        int bitCount = GetLengthBits(dPos-startPos);
                        int bits = (16 - bitCount);
                        ushort lengthMask = (ushort)((0xFFFF) >> bits);

                        while (candidate >= startPos)
                        {
                            if (buffer[candidate] == buffer[dPos])
                            {
                                int length = 1;

                                while (buffer.Length > dPos + length && buffer[candidate + length] == buffer[dPos + length] && length < lengthMask && dPos+length < dEnd)
                                {
                                    length++;
                                }
                                if (length > bestLength)
                                {
                                    bestCandidate = candidate;
                                    bestLength = length;
                                    if (bestLength == lengthMask)
                                    {
                                        break;
                                    }
                                }
                            }
                            candidate--;
                        }
                        if (bestLength >= 3)    //Copy token
                        {
                            tokenFlags |= (byte)(1 << i);

                            UInt16 offsetMask = (ushort)~lengthMask;
                            ushort token = (ushort)(((ushort)(dPos - (bestCandidate+1))) << (bitCount) | (ushort)(bestLength - 3));
                            Array.Copy(BitConverter.GetBytes(token), 0, comprBuffer, cPos, 2);
                            dPos = dPos + bestLength;
                            cPos += 2;
                            //SetCopy Token                        
                        }
                        else
                        {
                            comprBuffer[cPos++] = buffer[dPos++];
                        }
                    }
                    
                    else
                    {
                        comprBuffer[cPos++] = buffer[dPos++];
                    }
                    if (dPos >= dEnd) break;
                }
                comprBuffer[flagPos] = tokenFlags;
                flagPos = cPos++;
            }
            var ret = new byte[cPos - 1];
            Array.Copy(comprBuffer, ret, ret.Length);
            startPos = dEnd;
            return ret;
        }
        internal static byte[] DecompressPart(byte[] part)
        {
            return DecompressPart(part, 0);
        }
        /// <summary>
        /// Decompression using a run length encoding algorithm.
        /// See MS-OVBA Section 2.4
        /// </summary>
        /// <param name="part">Byte array to decompress</param>
        /// <param name="startPos"></param>
        /// <returns></returns>
        internal static byte[] DecompressPart(byte[] part, int startPos)
        {

            if (part[startPos] != 1)
            {
                return null;
            }
            MemoryStream ms = new MemoryStream(4096);
            int compressPos = startPos + 1;
            while(compressPos < part.Length-1)
            {
                DecompressChunk(ms, part, ref compressPos);
            }
            return ms.ToArray();
        }
        private static void DecompressChunk(MemoryStream ms, byte[] compBuffer, ref int pos)
        {
            ushort header = BitConverter.ToUInt16(compBuffer, pos);
            int  decomprPos=0;
            byte[] buffer = new byte[4198]; //Add an extra 100 byte. Some workbooks have overflowing worksheets.
            int size = (int)(header & 0xFFF)+3;
            int endPos = pos+size;
            int a = (int)(header & 0x7000) >> 12;
            int b = (int)(header & 0x8000) >> 15;
            pos += 2;
            if (b == 1) //Compressed chunk
            {
                while (pos < compBuffer.Length && pos < endPos)
                {
                    //Decompress token
                    byte token = compBuffer[pos++];
                    if (pos >= endPos)
                        break;
                    for (int i = 0; i < 8; i++)
                    {
                        //Literal token
                        if ((token & (1 << i)) == 0)
                        {
                            ms.WriteByte(compBuffer[pos]);  
                            buffer[decomprPos++] = compBuffer[pos++];
                        }
                        else //copy token
                        {
                            var t = BitConverter.ToUInt16(compBuffer, pos);
                            int bitCount = GetLengthBits(decomprPos);
                            int bits = (16 - bitCount);
                            ushort lengthMask = (ushort)((0xFFFF) >> bits);
                            UInt16 offsetMask = (ushort)~lengthMask;
                            var length = (lengthMask & t) + 3;
                            var offset = (offsetMask & t) >> (bitCount);
                            int source = decomprPos - offset - 1;
                            if (decomprPos + length >= buffer.Length)
                            {
                                // Be lenient on decompression, so extend our decompression
                                // buffer. Excel generated VBA projects do encounter this issue.
                                // One would think (not surprisingly that the VBA project spec)
                                // over emphasizes the size restrictions of a DecompressionChunk.
                                var largerBuffer = new byte[buffer.Length + 4098];
                                Array.Copy(buffer, largerBuffer, decomprPos);
                                buffer = largerBuffer;
                            }
                            
                            // Even though we've written to the MemoryStream,
                            // We still should decompress the token into this buffer
                            // in case a later token needs to use the bytes we're
                            // about to decompress.
                            for (int c = 0; c < length; c++)
                            {
                                ms.WriteByte(buffer[source]); //Must copy byte-wise because copytokens can overlap compressed buffer.
                                buffer[decomprPos++] = buffer[source++];
                            }

                            pos += 2;

                        }
                        if (pos >= endPos)
                            break;
                    }
                }
                return;
            }
            else //Raw chunk
            {
                ms.Write(compBuffer, pos, size);
                pos += size;
                return;
            }
        }
        private static int GetLengthBits(int decompPos)
        {
            if (decompPos <= 16)
            {
                return 12;
            }
            else if (decompPos <= 32)
            {
                return 11;
            }
            else if (decompPos <= 64)
            {
                return 10;
            }
            else if (decompPos <= 128)
            {
                return 9;
            }
            else if (decompPos <= 256)
            {
                return 8;
            }
            else if (decompPos <= 512)
            {
                return 7;
            }
            else if (decompPos <= 1024)
            {
                return 6;
            }
            else if (decompPos <= 2048)
            {
                return 5;
            }
            else if (decompPos <= 4096)
            {
                return 4;
            }
            else
            {
                //We should never end up here, but if so this is the formula to calculate the bits...
                return 12 - (int)Math.Truncate(Math.Log(decompPos - 1 >> 4, 2) + 1);
            }
        }
        #endregion
        #region "API declare"
        [ComImport]
        [Guid("0000000d-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IEnumSTATSTG
        {
            // The user needs to allocate an STATSTG array whose size is celt. 
            [PreserveSig]
            uint Next(
                uint celt,
                [MarshalAs(UnmanagedType.LPArray), Out] 
            System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt,
                out uint pceltFetched
            );

            void Skip(uint celt);

            void Reset();

            [return: MarshalAs(UnmanagedType.Interface)]
            IEnumSTATSTG Clone();
        }

        [ComImport]
        [Guid("0000000b-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IStorage
        {
            void CreateStream(
                /* [string][in] */ string pwcsName,
                /* [in] */ uint grfMode,
                /* [in] */ uint reserved1,
                /* [in] */ uint reserved2,
                /* [out] */ out comTypes.IStream ppstm);

            void OpenStream(
                /* [string][in] */ string pwcsName,
                /* [unique][in] */ IntPtr reserved1,
                /* [in] */ uint grfMode,
                /* [in] */ uint reserved2,
                /* [out] */ out comTypes.IStream ppstm);

            void CreateStorage(
                /* [string][in] */ string pwcsName,
                /* [in] */ uint grfMode,
                /* [in] */ uint reserved1,
                /* [in] */ uint reserved2,
                /* [out] */ out IStorage ppstg);

            void OpenStorage(
                /* [string][unique][in] */ string pwcsName,
                /* [unique][in] */ IStorage pstgPriority,
                /* [in] */ STGM grfMode,
                /* [unique][in] */ IntPtr snbExclude,
                /* [in] */ uint reserved,
                /* [out] */ out IStorage ppstg);

            void CopyTo(
                [InAttribute] uint ciidExclude,
                [InAttribute] Guid[] rgiidExclude,
                [InAttribute] IntPtr snbExclude,
                [InAttribute] IStorage pstgDest
            );

            void MoveElementTo(
                /* [string][in] */ string pwcsName,
                /* [unique][in] */ IStorage pstgDest,
                /* [string][in] */ string pwcsNewName,
                /* [in] */ uint grfFlags);

            void Commit(
                /* [in] */ uint grfCommitFlags);

            void Revert();

            void EnumElements(
                /* [in] */ uint reserved1,
                /* [size_is][unique][in] */ IntPtr reserved2,
                /* [in] */ uint reserved3,
                /* [out] */ out IEnumSTATSTG ppenum);

            void DestroyElement(
                /* [string][in] */ string pwcsName);

            void RenameElement(
                /* [string][in] */ string pwcsOldName,
                /* [string][in] */ string pwcsNewName);

            void SetElementTimes(
                /* [string][unique][in] */ string pwcsName,
                /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME patime,
                /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pmtime);

            void SetClass(
                /* [in] */ Guid clsid);

            void SetStateBits(
                /* [in] */ uint grfStateBits,
                /* [in] */ uint grfMask);

            void Stat(
                /* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                /* [in] */ uint grfStatFlag);

        }
        [ComVisible(false)]
        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000000A-0000-0000-C000-000000000046")]
        internal interface ILockBytes
        {
            void ReadAt(long ulOffset, System.IntPtr pv, int cb, out UIntPtr pcbRead);
            void WriteAt(long ulOffset, System.IntPtr pv, int cb, out UIntPtr pcbWritten);
            void Flush();
            void SetSize(long cb);
            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);
        }
        [Flags]
        internal enum STGM : int
        {
            DIRECT = 0x00000000,
            TRANSACTED = 0x00010000,
            SIMPLE = 0x08000000,
            READ = 0x00000000,
            WRITE = 0x00000001,
            READWRITE = 0x00000002,
            SHARE_DENY_NONE = 0x00000040,
            SHARE_DENY_READ = 0x00000030,
            SHARE_DENY_WRITE = 0x00000020,
            SHARE_EXCLUSIVE = 0x00000010,
            PRIORITY = 0x00040000,
            DELETEONRELEASE = 0x04000000,
            NOSCRATCH = 0x00100000,
            CREATE = 0x00001000,
            CONVERT = 0x00020000,
            FAILIFTHERE = 0x00000000,
            NOSNAPSHOT = 0x00200000,
            DIRECT_SWMR = 0x00400000,
        }

        internal enum STATFLAG : uint
        {
            STATFLAG_DEFAULT = 0,
            STATFLAG_NONAME = 1,
            STATFLAG_NOOPEN = 2
        }

        internal enum STGTY : int
        {
            STGTY_STORAGE = 1,
            STGTY_STREAM = 2,
            STGTY_LOCKBYTES = 3,
            STGTY_PROPERTY = 4
        }

        [DllImport("ole32.dll")]
        private static extern int StgIsStorageFile(
            [MarshalAs(UnmanagedType.LPWStr)] string pwcsName);
        [DllImport("ole32.dll")]
        private static extern int StgIsStorageILockBytes(
            ILockBytes plkbyt);


        [DllImport("ole32.dll")]
        static extern int StgOpenStorage(
            [MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
            IStorage pstgPriority,
            STGM grfMode,
            IntPtr snbExclude,
            uint reserved,
            out IStorage ppstgOpen);

        [DllImport("ole32.dll")]
        static extern int StgOpenStorageOnILockBytes(
            ILockBytes plkbyt,
            IStorage pStgPriority,
            STGM grfMode,
            IntPtr snbEnclude,
            uint reserved,
            out IStorage ppstgOpen);
        [DllImport("ole32.dll")]
        static extern int CreateILockBytesOnHGlobal(
            IntPtr hGlobal,
            bool fDeleteOnRelease,
            out ILockBytes ppLkbyt);

        [DllImport("ole32.dll")]
        static extern int StgCreateDocfileOnILockBytes(ILockBytes plkbyt, STGM grfMode, int reserved, out IStorage ppstgOpen);

        #endregion
        [SecuritySafeCritical]
        internal static int IsStorageFile(string Name)
        {
            return StgIsStorageFile(Name);
        }
        [SecuritySafeCritical]
        internal static int IsStorageILockBytes(ILockBytes lb)
        {
            return StgIsStorageILockBytes(lb);
        }
        [SecuritySafeCritical]
        internal static ILockBytes GetLockbyte(MemoryStream stream)
        {
            ILockBytes lb;
            var iret = CreateILockBytesOnHGlobal(IntPtr.Zero, true, out lb);
            byte[] docArray = stream.GetBuffer();

            IntPtr buffer = Marshal.AllocHGlobal(docArray.Length);
            Marshal.Copy(docArray, 0, buffer, docArray.Length);
            UIntPtr readSize;
            lb.WriteAt(0, buffer, docArray.Length, out readSize);
            Marshal.FreeHGlobal(buffer);

            return lb;
        }
        [SecuritySafeCritical]
        private MemoryStream ReadParts(IStorage storage, StoragePart storagePart)
        {
            MemoryStream ret = null;
            comTypes.STATSTG statstg;

            storage.Stat(out statstg, (uint)STATFLAG.STATFLAG_DEFAULT);

            IEnumSTATSTG pIEnumStatStg = null;
            storage.EnumElements(0, IntPtr.Zero, 0, out pIEnumStatStg);

            comTypes.STATSTG[] regelt = { statstg };
            uint fetched = 0;
            uint res = pIEnumStatStg.Next(1, regelt, out fetched);

            //if (regelt[0].pwcsName == "DataSpaces")
            //{
            //    PrintStorage(storage, regelt[0],"");
            //}
            while (res != 1)
            {
                foreach (var item in regelt)
                {
                    if (item.type == 1)
                    {
                        IStorage subStorage;
                        storage.OpenStorage(item.pwcsName, null, STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE, IntPtr.Zero, 0, out subStorage);
                        StoragePart subStoragePart=new StoragePart();
                        storagePart.SubStorage.Add(item.pwcsName, subStoragePart);
                        ReadParts(subStorage, subStoragePart);
                    }
                    else
                    {
                        storagePart.DataStreams.Add(item.pwcsName, GetOleStream(storage, item));                    
                    }
                }
                res = pIEnumStatStg.Next(1, regelt, out fetched);
            }
            Marshal.ReleaseComObject(pIEnumStatStg);
            return ret;
        }
        // Help method to print a storage part binary to c:\temp
        //private void PrintStorage(IStorage storage, System.Runtime.InteropServices.ComTypes.STATSTG sTATSTG, string topName)
        //{
        //    IStorage ds;
        //    if (topName.Length > 0)
        //    {
        //        topName = topName[0] < 'A' ? topName.Substring(1, topName.Length - 1) : topName;
        //    }
        //    storage.OpenStorage(sTATSTG.pwcsName,
        //        null,
        //        (uint)(STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE),
        //        IntPtr.Zero,
        //        0,
        //        out ds);

        //    System.Runtime.InteropServices.ComTypes.STATSTG statstgSub;
        //    ds.Stat(out statstgSub, (uint)STATFLAG.STATFLAG_DEFAULT);

        //    IEnumSTATSTG pIEnumStatStgSub = null;
        //    System.Runtime.InteropServices.ComTypes.STATSTG[] regeltSub = { statstgSub };
        //    ds.EnumElements(0, IntPtr.Zero, 0, out pIEnumStatStgSub);

        //    uint fetched = 0;
        //    while (pIEnumStatStgSub.Next(1, regeltSub, out fetched) == 0)
        //    {
        //        string sName = regeltSub[0].pwcsName[0] < 'A' ? regeltSub[0].pwcsName.Substring(1, regeltSub[0].pwcsName.Length - 1) : regeltSub[0].pwcsName;
        //        if (regeltSub[0].type == 1)
        //        {
        //            PrintStorage(ds, regeltSub[0], topName + sName + "_");
        //        }
        //        else if(regeltSub[0].type==2)
        //        {
        //            File.WriteAllBytes(@"c:\temp\" + topName + sName + ".bin", GetOleStream(ds, regeltSub[0]));
        //        }
        //    }
        //}    }
        /// <summary>
        /// Read the stream and return it as a byte-array
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="statstg"></param>
        /// <returns></returns>
        [SecuritySafeCritical]
        private byte[] GetOleStream(IStorage storage, comTypes.STATSTG statstg)
        {
            comTypes.IStream pIStream;
            storage.OpenStream(statstg.pwcsName,
               IntPtr.Zero,
               (uint)(STGM.READ | STGM.SHARE_EXCLUSIVE),
               0,
               out pIStream);

            byte[] data = new byte[statstg.cbSize];
            pIStream.Read(data, (int)statstg.cbSize, IntPtr.Zero);
            Marshal.ReleaseComObject(pIStream);

            return data;
        }

        [SecuritySafeCritical]
        internal byte[] Save()
        {
            ILockBytes lb;
            var iret = CreateILockBytesOnHGlobal(IntPtr.Zero, true, out lb);

            IStorage storage = null;
            byte[] ret = null;

            //Create the document in-memory
            if (StgCreateDocfileOnILockBytes(lb,
                    STGM.CREATE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE | STGM.TRANSACTED, 
                    0,
                    out storage)==0)
            {
                foreach(var store in this.Storage.SubStorage)
                {
                    CreateStore(store.Key, store.Value, storage);
                }
                CreateStreams(this.Storage, storage);                                
                lb.Flush();
                
                //Now copy the unmanaged stream to a byte array --> memory stream
                var statstg = new comTypes.STATSTG();
                lb.Stat(out statstg, 0);
                int size = (int)statstg.cbSize;
                IntPtr buffer = Marshal.AllocHGlobal(size);
                UIntPtr readSize;
                ret=new byte[size];
                lb.ReadAt(0, buffer, size, out readSize);
                Marshal.Copy(buffer, ret, 0, size);
                Marshal.FreeHGlobal(buffer);
            }
            Marshal.ReleaseComObject(storage);
            Marshal.ReleaseComObject(lb);

            return ret;
        }

        private void CreateStore(string name, StoragePart subStore, IStorage storage)
        {
            IStorage subStorage;
            storage.CreateStorage(name, (uint)(STGM.CREATE | STGM.WRITE | STGM.DIRECT | STGM.SHARE_EXCLUSIVE), 0, 0, out subStorage);
            storage.Commit(0);
            foreach (var store in subStore.SubStorage)
            {
                CreateStore(store.Key, store.Value, subStorage);
            }
            
            CreateStreams(subStore, subStorage);
        }

        private void CreateStreams(StoragePart subStore, IStorage subStorage)
        {
            foreach (var ds in subStore.DataStreams)
            {
                comTypes.IStream stream;
                subStorage.CreateStream(ds.Key, (uint)(STGM.CREATE | STGM.WRITE | STGM.DIRECT | STGM.SHARE_EXCLUSIVE), 0, 0, out stream);
                stream.Write(ds.Value, ds.Value.Length, IntPtr.Zero);
            }
            subStorage.Commit(0);
        }
			
    }
#endif
}