예제 #1
0
        private MemoryStream GetFileDescriptor(OleDataObjectItem[] SelectedItems)
        {
            MemoryStream FileDescriptorMemoryStream = new MemoryStream();

            // Write out the FILEGROUPDESCRIPTOR.cItems value
            FileDescriptorMemoryStream.Write(BitConverter.GetBytes(SelectedItems.Length), 0, sizeof(UInt32));

            Win32.NativeMethods.FILEDESCRIPTORW FileDescriptor = new Win32.NativeMethods.FILEDESCRIPTORW();
            foreach (OleDataObjectItem si in SelectedItems)
            {
                FileDescriptor.cFileName = si.FileName;
                Int64 FileWriteTimeUtc = si.WriteTime.ToFileTimeUtc();
                FileDescriptor.ftLastWriteTime.dwHighDateTime = (Int32)(FileWriteTimeUtc >> 32);
                FileDescriptor.ftLastWriteTime.dwLowDateTime  = (Int32)(FileWriteTimeUtc & 0xFFFFFFFF);
                FileDescriptor.nFileSizeHigh = (UInt32)(si.FileSize >> 32);
                FileDescriptor.nFileSizeLow  = (UInt32)(si.FileSize & 0xFFFFFFFF);
                FileDescriptor.dwFlags       = Win32.NativeMethods.FD_WRITESTIME | Win32.NativeMethods.FD_FILESIZE | Win32.NativeMethods.FD_PROGRESSUI;

                // Marshal the FileDescriptor structure into a byte array and write it to the MemoryStream.
                Int32  FileDescriptorSize    = Marshal.SizeOf(FileDescriptor);
                IntPtr FileDescriptorPointer = Marshal.AllocHGlobal(FileDescriptorSize);
                Marshal.StructureToPtr(FileDescriptor, FileDescriptorPointer, true);
                Byte[] FileDescriptorByteArray = new Byte[FileDescriptorSize];
                Marshal.Copy(FileDescriptorPointer, FileDescriptorByteArray, 0, FileDescriptorSize);
                Marshal.FreeHGlobal(FileDescriptorPointer);
                FileDescriptorMemoryStream.Write(FileDescriptorByteArray, 0, FileDescriptorByteArray.Length);
            }
            return(FileDescriptorMemoryStream);
        }
예제 #2
0
        private MemoryStream GetFileDescriptor(OleDataObjectItem[] SelectedItems)
        {
            MemoryStream FileDescriptorMemoryStream = new MemoryStream();
            // Write out the FILEGROUPDESCRIPTOR.cItems value
            FileDescriptorMemoryStream.Write(BitConverter.GetBytes(SelectedItems.Length), 0, sizeof(UInt32));

            Win32.NativeMethods.FILEDESCRIPTORW FileDescriptor = new Win32.NativeMethods.FILEDESCRIPTORW();
            foreach (OleDataObjectItem si in SelectedItems)
            {
                FileDescriptor.cFileName = si.FileName;
                Int64 FileWriteTimeUtc = si.WriteTime.ToFileTimeUtc();
                FileDescriptor.ftLastWriteTime.dwHighDateTime = (Int32)(FileWriteTimeUtc >> 32);
                FileDescriptor.ftLastWriteTime.dwLowDateTime = (Int32)(FileWriteTimeUtc & 0xFFFFFFFF);
                FileDescriptor.nFileSizeHigh = (UInt32)(si.FileSize >> 32);
                FileDescriptor.nFileSizeLow = (UInt32)(si.FileSize & 0xFFFFFFFF);
                FileDescriptor.dwFlags = Win32.NativeMethods.FD_WRITESTIME | Win32.NativeMethods.FD_FILESIZE | Win32.NativeMethods.FD_PROGRESSUI;

                // Marshal the FileDescriptor structure into a byte array and write it to the MemoryStream.
                Int32 FileDescriptorSize = Marshal.SizeOf(FileDescriptor);
                IntPtr FileDescriptorPointer = Marshal.AllocHGlobal(FileDescriptorSize);
                Marshal.StructureToPtr(FileDescriptor, FileDescriptorPointer, true);
                Byte[] FileDescriptorByteArray = new Byte[FileDescriptorSize];
                Marshal.Copy(FileDescriptorPointer, FileDescriptorByteArray, 0, FileDescriptorSize);
                Marshal.FreeHGlobal(FileDescriptorPointer);
                FileDescriptorMemoryStream.Write(FileDescriptorByteArray, 0, FileDescriptorByteArray.Length);
            }
            return FileDescriptorMemoryStream;
        }
예제 #3
0
        /// <summary>
        /// Retrieves the data associated with the specified data format, using a Boolean to determine whether to convert the data to the format.
        /// </summary>
        /// <param name="format">The format of the data to retrieve. See <see cref="T:System.Windows.Forms.DataFormats"></see> for predefined formats.</param>
        /// <param name="autoConvert">true to convert the data to the specified format; otherwise, false.</param>
        /// <returns>
        /// The data associated with the specified format, or null.
        /// </returns>
        public object GetData(string format, bool autoConvert)
        {
            //handle the "FileGroupDescriptor" and "FileContents" format request in this class otherwise pass through to underlying IDataObject
            switch (format)
            {
            case "FileGroupDescriptor":
                //override the default handling of FileGroupDescriptor which returns a
                //MemoryStream and instead return a string array of file names
                IntPtr fileGroupDescriptorAPointer = IntPtr.Zero;
                try
                {
                    //use the underlying IDataObject to get the FileGroupDescriptor as a MemoryStream
                    MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData("FileGroupDescriptor", autoConvert);
                    byte[]       fileGroupDescriptorBytes  = new byte[fileGroupDescriptorStream.Length];
                    fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
                    fileGroupDescriptorStream.Close();

                    //copy the file group descriptor into unmanaged memory
                    fileGroupDescriptorAPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
                    Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorAPointer, fileGroupDescriptorBytes.Length);

                    //read the cItem from the FILEGROUPDESCRIPTORA
                    int fileDescriptorCount = Marshal.ReadInt32(fileGroupDescriptorAPointer);

                    //create a new array to store file names in of the number of items in the file group descriptor
                    string[] fileNames = new string[fileDescriptorCount];

                    //get the pointer to the first file descriptor
                    IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorAPointer + Marshal.SizeOf(fileGroupDescriptorAPointer));

                    //loop for the number of files acording to the file group descriptor
                    for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileDescriptorCount; fileDescriptorIndex++)
                    {
                        //marshal the pointer top the file descriptor as a FILEDESCRIPTORA struct and get the file name
                        Win32.NativeMethods.FILEDESCRIPTORA fileDescriptor = (Win32.NativeMethods.FILEDESCRIPTORA)Marshal.PtrToStructure(fileDescriptorPointer, typeof(Win32.NativeMethods.FILEDESCRIPTORA));
                        fileNames[fileDescriptorIndex] = fileDescriptor.cFileName;

                        //move the file descriptor pointer to the next file descriptor
                        fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
                    }

                    //return the array of filenames
                    return(fileNames);
                }
                finally
                {
                    //free unmanaged memory pointer
                    Marshal.FreeHGlobal(fileGroupDescriptorAPointer);
                }

            case "FileGroupDescriptorW":
                //override the default handling of FileGroupDescriptorW which returns a
                //MemoryStream and instead return a string array of file names
                IntPtr fileGroupDescriptorWPointer = IntPtr.Zero;
                try
                {
                    //use the underlying IDataObject to get the FileGroupDescriptorW as a MemoryStream
                    MemoryStream fileGroupDescriptorStream = (MemoryStream)this.underlyingDataObject.GetData("FileGroupDescriptorW");
                    byte[]       fileGroupDescriptorBytes  = new byte[fileGroupDescriptorStream.Length];
                    fileGroupDescriptorStream.Read(fileGroupDescriptorBytes, 0, fileGroupDescriptorBytes.Length);
                    fileGroupDescriptorStream.Close();

                    //copy the file group descriptor into unmanaged memory
                    fileGroupDescriptorWPointer = Marshal.AllocHGlobal(fileGroupDescriptorBytes.Length);
                    Marshal.Copy(fileGroupDescriptorBytes, 0, fileGroupDescriptorWPointer, fileGroupDescriptorBytes.Length);

                    //read the cItem from the FILEGROUPDESCRIPTORW
                    int fileDescriptorCount = Marshal.ReadInt32(fileGroupDescriptorWPointer);

                    //create a new array to store file names in of the number of items in the file group descriptor
                    string[] fileNames = new string[fileDescriptorCount];

                    //get the pointer to the first file descriptor
                    IntPtr fileDescriptorPointer = (IntPtr)((int)fileGroupDescriptorWPointer + Marshal.SizeOf(fileGroupDescriptorWPointer));

                    //loop for the number of files acording to the file group descriptor
                    for (int fileDescriptorIndex = 0; fileDescriptorIndex < fileDescriptorCount; fileDescriptorIndex++)
                    {
                        //marshal the pointer top the file descriptor as a FILEDESCRIPTORW struct and get the file name
                        Win32.NativeMethods.FILEDESCRIPTORW fileDescriptor = (Win32.NativeMethods.FILEDESCRIPTORW)Marshal.PtrToStructure(fileDescriptorPointer, typeof(Win32.NativeMethods.FILEDESCRIPTORW));
                        fileNames[fileDescriptorIndex] = fileDescriptor.cFileName;

                        //move the file descriptor pointer to the next file descriptor
                        fileDescriptorPointer = (IntPtr)((int)fileDescriptorPointer + Marshal.SizeOf(fileDescriptor));
                    }

                    //return the array of filenames
                    return(fileNames);
                }
                finally
                {
                    //free unmanaged memory pointer
                    Marshal.FreeHGlobal(fileGroupDescriptorWPointer);
                }

            case "FileContents":
                //override the default handling of FileContents which returns the
                //contents of the first file as a memory stream and instead return
                //a array of MemoryStreams containing the data to each file dropped

                //get the array of filenames which lets us know how many file contents exist
                string[] fileContentNames = (string[])this.GetData("FileGroupDescriptor");

                //create a MemoryStream array to store the file contents
                MemoryStream[] fileContents = new MemoryStream[fileContentNames.Length];

                //loop for the number of files acording to the file names
                for (int fileIndex = 0; fileIndex < fileContentNames.Length; fileIndex++)
                {
                    //get the data at the file index and store in array
                    fileContents[fileIndex] = this.GetData(format, fileIndex);
                }

                //return array of MemoryStreams containing file contents
                return(fileContents);
            }

            //use underlying IDataObject to handle getting of data
            return(this.underlyingDataObject.GetData(format, autoConvert));
        }