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); } }
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); } }
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); } } }
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); } } }
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); }
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); }
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); }
public OutlookDataObject(NativeMethods.IDataObject innerData) { this.innerData = innerData; }
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); } }
public static extern int DoDragDrop(NativeMethods.IDataObject pDataObj, NativeMethods.IDropSource pDropSource, uint dwOKEffects, uint[] pdwEffect);
public static extern int DoDragDrop(NativeMethods.IDataObject pDataObj, IntPtr pDropSource, uint dwOKEffects, out uint pdwEffect);
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); } } }
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); }