Пример #1
0
        public static int DoDragDropHook(NativeMethods.IDataObject pDataObj, IntPtr pDropSource, uint dwOKEffects, out uint pdwEffect)
        {
            try
            {
                log.Info("Drag started");
                if (!DataObjectHelper.GetDataPresent(pDataObj, "FileGroupDescriptorW") && !DataObjectHelper.GetDataPresent(pDataObj, "FileGroupDescriptor"))
                {
                    log.Info("No virtual files found -- continuing original drag");
                    return(NativeMethods.DoDragDrop(pDataObj, pDropSource, dwOKEffects, out pdwEffect));
                }

                //Start new drag
                log.Info("Virtual files found -- starting new drag adding CF_HDROP format");
                log.InfoFormat("Files: {0}", string.Join(",", DataObjectHelper.GetFilenames(pDataObj)));

                OutlookDataObject newDataObj = new OutlookDataObject(pDataObj);
                int result = NativeMethods.DoDragDrop(newDataObj, pDropSource, dwOKEffects, out pdwEffect);

                //If files were dropped and drop effect was "move", then override to "copy" so original item is not deleted
                if (newDataObj.FilesDropped && pdwEffect == NativeMethods.DROPEFFECT_MOVE)
                {
                    pdwEffect = NativeMethods.DROPEFFECT_COPY;
                }

                //Get result
                log.InfoFormat("DoDragDrop effect: {0} result: {1}", pdwEffect, result);
                return(result);
            }
            catch (Exception ex)
            {
                log.Warn("Dragging error", ex);
                pdwEffect = NativeMethods.DROPEFFECT_NONE;
                return(NativeMethods.DRAGDROP_S_CANCEL);
            }
        }
Пример #2
0
        public static int DoDragDropHook(NativeMethods.IDataObject pDataObj, NativeMethods.IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect)
        {
            try
            {
                log.Info("Drag started");
                if (!DataObjectHelper.GetDataPresent(pDataObj, "FileGroupDescriptorW"))
                {
                    log.Info("No virtual files found -- continuing original drag");
                    return(NativeMethods.DoDragDrop(pDataObj, pDropSource, dwOKEffects, pdwEffect));
                }

                //Start new drag
                log.Info("Virtual files found -- starting new drag adding CF_HDROP format");
                log.InfoFormat("Files: {0}", string.Join(",", DataObjectHelper.GetFilenames(pDataObj)));

                NativeMethods.IDataObject newDataObj = new OutlookDataObject(pDataObj);
                int result = NativeMethods.DoDragDrop(newDataObj, pDropSource, dwOKEffects, pdwEffect);

                //Get result
                log.InfoFormat("DoDragDrop result: {0}", result);
                return(result);
            }
            catch (Exception ex)
            {
                log.Warn("Dragging error", ex);
                return(NativeMethods.DRAGDROP_S_CANCEL);
            }
        }
Пример #3
0
        internal static void ReadFileContents(NativeMethods.IDataObject data, int index, Stream stream)
        {
            STGMEDIUM medium = new STGMEDIUM();

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

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

                //Read medium into stream
                ReadMediumIntoStream(medium, stream);
            }
            finally
            {
                //Release all unmanaged objects
                if (medium.pUnkForRelease == null)
                {
                    NativeMethods.ReleaseStgMedium(ref medium);
                }
            }
        }
Пример #4
0
        internal static void ReadFileContents(NativeMethods.IDataObject data, int index, Stream stream)
        {
            STGMEDIUM medium = new STGMEDIUM();

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

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

                //Read medium into stream
                ReadMediumIntoStream(medium, stream);
            }
            finally
            {
                //Release all unmanaged objects
                if (medium.pUnkForRelease == null)
                {
                    NativeMethods.ReleaseStgMedium(ref medium);
                }
            }
        }
Пример #5
0
        internal static string[] GetFilenames(NativeMethods.IDataObject data)
        {
            //Try Unicode first
            string[] filenames = GetFilenamesUnicode(data);

            //If Unicode returns null, try ANSI
            if (filenames == null)
            {
                filenames = GetFilenamesAnsi(data);
            }

            return(filenames);
        }
Пример #6
0
        internal static bool GetDataPresent(NativeMethods.IDataObject data, string formatName)
        {
            //Check if drag contains virtual files
            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;

            return(data.QueryGetData(format) == NativeMethods.S_OK);
        }
Пример #7
0
        internal static bool GetDataPresent(NativeMethods.IDataObject data, string formatName)
        {
            //Check if data is present
            log.DebugFormat("Get data present: {0}", formatName);
            FORMATETC format = new FORMATETC();

            format.cfFormat = (short)GetClipboardFormat(formatName);
            format.dwAspect = DVASPECT.DVASPECT_CONTENT;
            format.lindex   = -1;
            format.ptd      = IntPtr.Zero;
            format.tymed    = TYMED.TYMED_ISTREAM | TYMED.TYMED_ISTORAGE | TYMED.TYMED_HGLOBAL;

            return(data.QueryGetData(format) == NativeMethods.S_OK);
        }
Пример #8
0
 public OutlookDataObject(NativeMethods.IDataObject innerData)
 {
     this.innerData = innerData;
 }
Пример #9
0
        internal static string[] GetFilenamesAnsi(NativeMethods.IDataObject data)
        {
            IntPtr fgdaPtr = IntPtr.Zero;

            try
            {
                //Define FileGroupDescriptor format
                FORMATETC format = new FORMATETC();
                format.cfFormat = (short)System.Windows.Forms.DataFormats.GetFormat("FileGroupDescriptor").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 byte array
                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);
                Marshal.Copy(bytes, 0, fgdaPtr, bytes.Length);

                //Marshal the unmanaged memory to a FILEGROUPDESCRIPTORA struct
                object fgdObj = Marshal.PtrToStructure(fgdaPtr, typeof(NativeMethods.FILEGROUPDESCRIPTORA));
                NativeMethods.FILEGROUPDESCRIPTORA fgd = (NativeMethods.FILEGROUPDESCRIPTORA)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 FILEDESCRIPTORA struct
                    object fdObj = Marshal.PtrToStructure(fdPtr, typeof(NativeMethods.FILEDESCRIPTORA));
                    NativeMethods.FILEDESCRIPTORA fd = (NativeMethods.FILEDESCRIPTORA)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);
            }
        }
Пример #10
0
 public static extern int DoDragDrop(NativeMethods.IDataObject pDataObj, NativeMethods.IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect);
Пример #11
0
 public static extern int DoDragDrop(NativeMethods.IDataObject pDataObj, IntPtr pDropSource, uint dwOKEffects, out uint pdwEffect);
Пример #12
0
        internal static string[] GetFilenamesAnsi(NativeMethods.IDataObject data)
        {
            log.Debug("Getting filenames (ANSI)");
            IntPtr    ptrFgd = IntPtr.Zero;
            STGMEDIUM medium = new STGMEDIUM();

            try
            {
                //Define FileGroupDescriptor format
                FORMATETC format = new FORMATETC();
                format.cfFormat = (short)GetClipboardFormat("FileGroupDescriptor");
                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 FileGroupDescriptor 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 FILEGROUPDESCRIPTORA struct
                log.Debug("Marshaling unmanaged memory into FILEGROUPDESCRIPTORA struct");
                NativeMethods.FILEGROUPDESCRIPTORA fgd = (NativeMethods.FILEGROUPDESCRIPTORA)Marshal.PtrToStructure(ptrFgd, typeof(NativeMethods.FILEGROUPDESCRIPTORA));
                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 fdPtr = 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("Filenames found: {0}", string.Join(", ", filenames));

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

                    //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.Add(fdPtr, 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);
                }
            }
        }
Пример #13
0
        private DirectoryObject[] ProcessSelections(IntPtr dataObj)
        {
            if (dataObj == IntPtr.Zero)
            {
                throw new ArgumentNullException("dataObj");
            }

            DirectoryObject[] selections = null;

            // The STGMEDIUM structure is a generalized global memory handle used for data transfer operations
            NativeMethods.STGMEDIUM stg = new NativeMethods.STGMEDIUM();
            stg.tymed          = (uint)NativeMethods.TYMED.TYMED_HGLOBAL;
            stg.hGlobal        = IntPtr.Zero;
            stg.pUnkForRelease = IntPtr.Zero;

            // The FORMATETC structure is a generalized Clipboard format.
            NativeMethods.FORMATETC fe = new NativeMethods.FORMATETC();

            // The CFSTR_DSOP_DS_SELECTION_LIST clipboard format is provided by the IDataObject obtained by calling IDsObjectPicker::InvokeDialog
            fe.cfFormat = (uint)DataFormats.GetFormat(NativeMethods.CLIPBOARD_FORMAT.CFSTR_DSOP_DS_SELECTION_LIST).Id;

            fe.ptd = IntPtr.Zero;

            // DVASPECT_CONTENT = 1
            fe.dwAspect = 1;

            // all of the data
            fe.lindex = -1;

            // The storage medium is a global memory handle (HGLOBAL)
            fe.tymed = (uint)NativeMethods.TYMED.TYMED_HGLOBAL;

            NativeMethods.DS_SELECTION[] dataArray = null;

            int dsAttributesCount = 0;

            NativeMethods.DS_SELECTION_ATTRIBUTES[] dsAttributes = null;

            NativeMethods.IDataObject typedObjectForIUnknown = (NativeMethods.IDataObject)Marshal.GetTypedObjectForIUnknown(dataObj, typeof(NativeMethods.IDataObject));
            if (typedObjectForIUnknown.GetData(ref fe, ref stg) == 0)
            {
                IntPtr ptr = NativeMethods.GlobalLock(stg.hGlobal);

                try
                {
                    NativeMethods.DS_SELECTION_LIST ds_selection_list = (NativeMethods.DS_SELECTION_LIST)Marshal.PtrToStructure(ptr, typeof(NativeMethods.DS_SELECTION_LIST));
                    int numberOfItems = (int)ds_selection_list.cItems;
                    dsAttributesCount = (int)ds_selection_list.cFetchedAttributes;

                    selections = new DirectoryObject[numberOfItems];

                    if (numberOfItems > 0)
                    {
                        dataArray    = new NativeMethods.DS_SELECTION[numberOfItems];
                        dsAttributes = new NativeMethods.DS_SELECTION_ATTRIBUTES[numberOfItems];

                        IntPtr currentPtr = (IntPtr)(((long)ptr) + Marshal.SizeOf(ds_selection_list));

                        byte[] binaryForm = null;

                        for (int index = 0; index < numberOfItems; index++)
                        {
                            dataArray[index] = new NativeMethods.DS_SELECTION();
                            dataArray[index] = (NativeMethods.DS_SELECTION)Marshal.PtrToStructure(currentPtr, typeof(NativeMethods.DS_SELECTION));
                            if ((length > 0) && (dsAttributesCount > 0))
                            {
                                dsAttributes[index] = new NativeMethods.DS_SELECTION_ATTRIBUTES();
                                dsAttributes[index].attributeValues = Marshal.GetObjectsForNativeVariants(dataArray[index].pvarFetchedAttributes, dsAttributesCount);

                                binaryForm = dsAttributes[index].attributeValues[0] as byte[];
                            }

                            string schemaClassName = dataArray[index].pwzClass;
                            string name            = dataArray[index].pwzName;
                            string upn             = dataArray[index].pwzUPN;
                            string path            = dataArray[index].pwzADsPath;

                            selections[index]           = new DirectoryObject(schemaClassName, name, upn, path);
                            selections[index].BinarySid = binaryForm;

                            currentPtr = (IntPtr)(((long)currentPtr) + Marshal.SizeOf(dataArray[index]));
                        }
                    }
                }
                finally
                {
                    NativeMethods.GlobalUnlock(stg.hGlobal);
                }
            }

            return(selections);
        }