Ejemplo n.º 1
0
        internal static string[] GetFilenamesUnicode(NativeMethods.IDataObject data)
        {
            IntPtr fgdaPtr = IntPtr.Zero;

            try
            {
                //Define FileGroupDescriptorW format
                FORMATETC format = new FORMATETC();
                format.cfFormat = (short)System.Windows.Forms.DataFormats.GetFormat("FileGroupDescriptorW").Id;
                format.dwAspect = DVASPECT.DVASPECT_CONTENT;
                format.lindex   = -1;
                format.ptd      = IntPtr.Zero;
                format.tymed    = TYMED.TYMED_ISTREAM | TYMED.TYMED_ISTORAGE | TYMED.TYMED_HGLOBAL;

                //Query if format exists in data
                if (data.QueryGetData(format) != NativeMethods.S_OK)
                {
                    return(null);
                }

                //Get data into medium
                STGMEDIUM medium = new STGMEDIUM();
                data.GetData(format, out medium);

                //Read medium into string
                byte[] bytes;
                using (MemoryStream stream = new MemoryStream())
                {
                    DataObjectHelper.ReadMediumIntoStream(medium, stream);
                    bytes = new byte[stream.Length];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(bytes, 0, bytes.Length);
                }

                //Copy the file group descriptor into unmanaged memory
                fgdaPtr = Marshal.AllocHGlobal(bytes.Length);
                if (fgdaPtr == IntPtr.Zero)
                {
                    throw new OutOfMemoryException();
                }
                Marshal.Copy(bytes, 0, fgdaPtr, bytes.Length);

                //Marshal the unmanaged memory to a FILEGROUPDESCRIPTORA struct
                object fgdObj = Marshal.PtrToStructure(fgdaPtr, typeof(NativeMethods.FILEGROUPDESCRIPTORW));
                NativeMethods.FILEGROUPDESCRIPTORW fgd = (NativeMethods.FILEGROUPDESCRIPTORW)fgdObj;

                //Create an array to store file names
                string[] filenames = new string[fgd.cItems];

                //Get the pointer to the first file descriptor
                IntPtr fdPtr = (IntPtr)((int)fgdaPtr + Marshal.SizeOf(fgdaPtr));

                //Loop for the number of files acording to the file group descriptor
                for (int fdIndex = 0; fdIndex < fgd.cItems; fdIndex++)
                {
                    //Marshal the pointer to the file descriptor as a FILEDESCRIPTORW struct
                    object fdObj = Marshal.PtrToStructure(fdPtr, typeof(NativeMethods.FILEDESCRIPTORW));
                    NativeMethods.FILEDESCRIPTORW fd = (NativeMethods.FILEDESCRIPTORW)fdObj;

                    //Get filename of file descriptor and put in array
                    filenames[fdIndex] = fd.cFileName;

                    //Move the file descriptor pointer to the next file descriptor
                    fdPtr = (IntPtr)((int)fdPtr + Marshal.SizeOf(fd));
                }

                return(filenames);
            }
            finally
            {
                Marshal.FreeHGlobal(fgdaPtr);
            }
        }
Ejemplo n.º 2
0
        internal static string[] GetFilenamesUnicode(NativeMethods.IDataObject data)
        {
            log.Debug("Getting filenames (Unicode)");
            IntPtr    ptrFgd = IntPtr.Zero;
            STGMEDIUM medium = new STGMEDIUM();

            try
            {
                //Define FileGroupDescriptorW format
                FORMATETC format = new FORMATETC();
                format.cfFormat = (short)GetClipboardFormat("FileGroupDescriptorW");
                format.dwAspect = DVASPECT.DVASPECT_CONTENT;
                format.lindex   = -1;
                format.ptd      = IntPtr.Zero;
                format.tymed    = TYMED.TYMED_ISTREAM | TYMED.TYMED_ISTORAGE | TYMED.TYMED_HGLOBAL;

                //Query if format exists in data
                if (data.QueryGetData(format) != NativeMethods.S_OK)
                {
                    log.Debug("No filenames found");
                    return(null);
                }

                //Get data into medium
                int retVal = data.GetData(format, out medium);
                if (retVal != NativeMethods.S_OK)
                {
                    throw new Exception(string.Format("Could not get FileGroupDescriptorW format.  Error returned: {0}", retVal));
                }

                //Read medium into byte array
                log.Debug("Reading structure into memory stream");
                byte[] bytes;
                using (MemoryStream stream = new MemoryStream())
                {
                    DataObjectHelper.ReadMediumIntoStream(medium, stream);
                    bytes = new byte[stream.Length];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(bytes, 0, bytes.Length);
                }

                //Copy byte array into unmanaged memory
                log.Debug("Copying structure into unmanaged memory");
                ptrFgd = Marshal.AllocHGlobal(bytes.Length);
                Marshal.Copy(bytes, 0, ptrFgd, bytes.Length);

                //Marshal unmanaged memory to a FILEGROUPDESCRIPTORW struct
                log.Debug("Marshaling unmanaged memory into FILEGROUPDESCRIPTORW struct");
                NativeMethods.FILEGROUPDESCRIPTORW fgd = (NativeMethods.FILEGROUPDESCRIPTORW)Marshal.PtrToStructure(ptrFgd, typeof(NativeMethods.FILEGROUPDESCRIPTORW));
                log.Debug(string.Format("Files found: {0}", fgd.cItems));

                //Create an array to store file names
                string[] filenames = new string[fgd.cItems];

                //Get the pointer to the first file descriptor
                IntPtr ptrFd = IntPtr.Add(ptrFgd, sizeof(uint));

                //Loop for the number of files acording to the file group descriptor
                for (int fdIndex = 0; fdIndex < fgd.cItems; fdIndex++)
                {
                    log.DebugFormat("Getting filename {0}", fdIndex);

                    //Marshal pointer to a FILEDESCRIPTORW struct
                    NativeMethods.FILEDESCRIPTORW fd = (NativeMethods.FILEDESCRIPTORW)Marshal.PtrToStructure(ptrFd, typeof(NativeMethods.FILEDESCRIPTORW));

                    //Get filename of file descriptor and put in array
                    filenames[fdIndex] = fd.cFileName;

                    //Move the file descriptor pointer to the next file descriptor
                    ptrFd = IntPtr.Add(ptrFd, Marshal.SizeOf(fd));
                }

                log.DebugFormat("Filenames found: {0}", string.Join(", ", filenames));
                return(filenames);
            }
            finally
            {
                //Release all unmanaged objects
                Marshal.FreeHGlobal(ptrFgd);
                if (medium.pUnkForRelease == null)
                {
                    NativeMethods.ReleaseStgMedium(ref medium);
                }
            }
        }