Example #1
0
        /// <summary>
        /// Write the file contents to the specified path
        /// </summary>
        /// <param name="filePath">path to write file contents to</param>
        private void Write(string filePath)
        {
            // get the data in any format that it might be rendered in
            OleStgMedium storage = (OleStgMedium)oleDataObject.GetData(
                fileIndex, DataFormatsEx.FileContentsFormat,
                TYMED.ISTORAGE | TYMED.ISTREAM | TYMED.FILE | TYMED.HGLOBAL);

            // check for no storage
            if (storage == null)
            {
                throw new ApplicationException(
                          "FileContents used unexpected storage type");
            }

            // copy the data to a file (implemented differently for each storage type)
            using (storage)
            {
                // structured storage
                if (storage is OleStgMediumISTORAGE)
                {
                    OleStgMediumISTORAGE istorage = storage as OleStgMediumISTORAGE;
                    CopyStorageToFile(istorage.Storage, filePath);
                }

                // stream
                else if (storage is OleStgMediumISTREAM)
                {
                    OleStgMediumISTREAM istream = storage as OleStgMediumISTREAM;
                    CopyStreamToFile(istream.Stream, filePath);
                }

                // temporary file
                else if (storage is OleStgMediumFILE)
                {
                    OleStgMediumFILE file = storage as OleStgMediumFILE;
                    CopyFileToFile(file.Path, filePath);
                }

                // global memory
                else if (storage is OleStgMediumHGLOBAL)
                {
                    OleStgMediumHGLOBAL hglobal = storage as OleStgMediumHGLOBAL;
                    CopyHGLOBALToFile(hglobal.Handle, filePath);
                }
                else
                {
                    throw new ApplicationException(
                              "FileContents used unexpected storage type");
                }
            }
        }
        /// <summary>
        /// Retrieves the bytes representing the data in the HTML format of the HTMLData's
        /// IDataObject.
        /// </summary>
        /// <returns>The bytes representing the HTML in the IDataObject</returns>
        private byte[] GetHTMLBytes(OleStgMediumHGLOBAL storage)
        {
            // NOTE: Our theory about where/why the .NET implementation is failing
            // is that they probably assumed that the CF_HTML clipboard data was raw
            // Unicode and called Marshal.PtrToStringUni to convert it! CF_HTML is
            // in fact UTF8-encoded, so we need to first move it into a .NET byte
            // array and then UTF8-decode it.

            // get a non-movable pointer to the global memory
            IntPtr htmlBytes = Kernel32.GlobalLock(storage.Handle);

            if (htmlBytes == IntPtr.Zero)
            {
                Debug.Assert(false, "Failed to get the pointer for HTML Bytes");
                return(null);
            }

            // move the unmanaged global memory block into a managed byte array
            try
            {
                // scan to see where the null terminator is
                byte b         = 0;
                int  byteCount = 0;

                // Winlive 267804:
                // In some instances office doesn't supply a \0 at the end of the body.
                // Now we add a check to make sure we don't AV
                int maxArraySize = (int)Kernel32.GlobalSize(htmlBytes).ToUInt32();

                do
                {
                    b = Marshal.ReadByte(htmlBytes, byteCount);
                    byteCount++;
                } while (b != 0 && byteCount < maxArraySize);

                // allocate a byte array and copy the unmanged memory to it
                byte[] bytes = new byte[byteCount];
                Marshal.Copy(htmlBytes, bytes, 0, byteCount);

                return(bytes);
            }
            finally
            {
                // always unlock the global memory handle
                Kernel32.GlobalUnlock(storage.Handle);
            }
        }
        /// <summary>
        /// Utility function to extract an array of file contents file descriptors from
        /// an IDataObject instnace
        /// </summary>
        /// <param name="dataObject">data object to extract descriptors from</param>
        /// <returns>array of file descriptors</returns>
        public static FileDescriptor[] GetFileDescriptors(IDataObject dataObject)
        {
            // Use an OleDataObject
            OleDataObject oleDataObject = OleDataObject.CreateFrom(dataObject);

            if (oleDataObject == null)
            {
                const string message = "DataObject not valid for FileContents!";
                Debug.Fail(message);
                throw
                    new InvalidOperationException(message);
            }

            // Try to get the data as FileGroupDescriptorW then try to get it
            // as FileGroupDescriptor
            bool bFileNameIsWide;
            OleStgMediumHGLOBAL stgMedium = (OleStgMediumHGLOBAL)oleDataObject.GetData(
                DataFormatsEx.FileGroupDescriptorWFormat, TYMED.HGLOBAL);

            if (stgMedium != null)
            {
                bFileNameIsWide = true;
            }
            else
            {
                stgMedium = (OleStgMediumHGLOBAL)oleDataObject.GetData(
                    DataFormatsEx.FileGroupDescriptorFormat, TYMED.HGLOBAL);

                if (stgMedium != null)
                {
                    bFileNameIsWide = false;
                }
                else
                {
                    const string message = "File group descriptor not available!";
                    Debug.Fail(message);
                    throw
                        new InvalidOperationException(message);
                }
            }


            // Copy the descriptors
            using ( stgMedium )
            {
                using (HGlobalLock globalMem = new HGlobalLock(stgMedium.Handle))
                {
                    // get a pointer to the count
                    IntPtr pCount = globalMem.Memory;

                    // determine the number of file descriptors
                    Int32 count = Marshal.ReadInt32(pCount);

                    // get a pointer to the descriptors
                    IntPtr pDescriptors =
                        new IntPtr(globalMem.Memory.ToInt32() + Marshal.SizeOf(count));

                    // allocate the array of structures that will be returned
                    FileDescriptor[] descriptors = new FileDescriptor[count];

                    // determine the sizes of the various data elements
                    const int FILENAME_BUFFER_SIZE = 260;
                    int       headerSize           = Marshal.SizeOf(typeof(FILEDESCRIPTOR_HEADER));
                    int       fileNameSize         = bFileNameIsWide ? FILENAME_BUFFER_SIZE * 2 : FILENAME_BUFFER_SIZE;
                    int       totalSize            = headerSize + fileNameSize;

                    // iterate through the memory block copying the FILEDESCRIPTOR structures
                    for (int i = 0; i < count; i++)
                    {
                        // determine the addresses of the various data elements
                        IntPtr pAddr         = new IntPtr(pDescriptors.ToInt32() + (i * totalSize));
                        IntPtr pFileNameAddr = new IntPtr(pAddr.ToInt32() + headerSize);

                        // copy the header
                        descriptors[i].header = (FILEDESCRIPTOR_HEADER)
                                                Marshal.PtrToStructure(pAddr, typeof(FILEDESCRIPTOR_HEADER));

                        // copy the file name (use Unicode or Ansi depending upon descriptor type)
                        if (bFileNameIsWide)
                        {
                            descriptors[i].fileName = Marshal.PtrToStringUni(pFileNameAddr);
                        }
                        else
                        {
                            descriptors[i].fileName = Marshal.PtrToStringAnsi(pFileNameAddr);
                        }
                    }

                    // return the descriptors
                    return(descriptors);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Retrieves the bytes representing the data in the HTML format of the HTMLData's
        /// IDataObject.
        /// </summary>
        /// <returns>The bytes representing the HTML in the IDataObject</returns>
        private byte[] GetHTMLBytes(OleStgMediumHGLOBAL storage)
        {
            // NOTE: Our theory about where/why the .NET implementation is failing
            // is that they probably assumed that the CF_HTML clipboard data was raw
            // Unicode and called Marshal.PtrToStringUni to convert it! CF_HTML is
            // in fact UTF8-encoded, so we need to first move it into a .NET byte
            // array and then UTF8-decode it.

            // get a non-movable pointer to the global memory
            IntPtr htmlBytes = Kernel32.GlobalLock(storage.Handle);
            if (htmlBytes == IntPtr.Zero)
            {
                Debug.Assert(false, "Failed to get the pointer for HTML Bytes");
                return null;
            }

            // move the unmanaged global memory block into a managed byte array
            try
            {
                // scan to see where the null terminator is
                byte b = 0;
                int byteCount = 0;

                // Winlive 267804:
                // In some instances office doesn't supply a \0 at the end of the body.
                // Now we add a check to make sure we don't AV
                int maxArraySize = (int)Kernel32.GlobalSize(htmlBytes).ToUInt32();

                do
                {
                    b = Marshal.ReadByte(htmlBytes, byteCount);
                    byteCount++;
                } while (b != 0 && byteCount < maxArraySize);

                // allocate a byte array and copy the unmanged memory to it
                byte[] bytes = new byte[byteCount];
                Marshal.Copy(htmlBytes, bytes, 0, byteCount);

                return bytes;

            }
            finally
            {
                // always unlock the global memory handle
                Kernel32.GlobalUnlock(storage.Handle);
            }

        }