Пример #1
0
        private void HandleReceivedFileDrop(XSelectionEvent evt)
        {
            try
            {
                int ret = XGetWindowProperty(xConnection.XDisplay, xConnection.XCbWindow, evt.property, 0, 0, false, new IntPtr(0), out IntPtr retType,
                                             out int format, out int nItems, out int dataSize, out IntPtr prop_return);
                XFree(prop_return);

                XGetWindowProperty(xConnection.XDisplay, xConnection.XCbWindow, evt.property, 0, dataSize, false, new IntPtr(0), out IntPtr returned_type,
                                   out format, out nItems, out int remBytes, out prop_return);

                string rawFileList = Marshal.PtrToStringAuto(prop_return, nItems);

                ISLogger.Write(rawFileList);

                string[] list = rawFileList.Split('\n');

                string[] sanList = new string[list.Length];
                for (int i = 0; i < list.Length; i++)
                {
                    sanList[i] = list[i].Trim().Replace("file://", "");
                }

                XFree(prop_return);

                //Now we need to get the data for the listed files...

                ClipboardVirtualFileData files = ReadFileDrop(sanList);
                OnClipboardDataChanged(files);
            }catch (Exception ex)
            {
                ISLogger.Write("An error occurred while handling a clipboard file drop: " + ex.Message);
            }
        }
Пример #2
0
        /// <summary>
        /// Begins a file dragdrop operation, and assigns an access token to the operation
        /// </summary>
        /// <param name="cbFiles"></param>
        /// <param name="host"></param>
        /// <param name="operationId"></param>
        private async Task BeginFileOperationAsync(ClipboardVirtualFileData cbFiles, ISServerSocket host, Guid operationId)
        {
            Guid fileAccesstoken = Guid.Empty;

            DragDropOperation newOperation = new DragDropOperation(cbFiles, host, operationId);

            try
            {
                fileAccesstoken = await CreateAccessTokenForOperation(newOperation);
            }
            catch (Exception ex)
            {
                ISLogger.Write("DragDropController: Cancelling operation, could not generate file access token: " + ex.Message);
                return;
            }
            newOperation.RemoteFileAccessToken = fileAccesstoken;

            //Create events, incase the files are dropped on localhost
            if (!newOperation.Host.IsLocalhost)
            {
                for (int i = 0; i < cbFiles.AllFiles.Count; i++)
                {
                    cbFiles.AllFiles[i].RemoteAccessToken = fileAccesstoken;
                    cbFiles.AllFiles[i].ReadDelegate      = File_RequestDataAsync;
                    cbFiles.AllFiles[i].ReadComplete     += VirtualFile_ReadComplete;
                    cbFiles.AllFiles[i].FileOperationId   = newOperation.OperationId;
                }
            }

            //If the previous dragdrop operation is still transfering files, store it so that the files can keep being transfered
            if (CurrentOperation != null && CurrentOperation.State == DragDropState.TransferingFiles)
            {
                previousOperationIds.Add(CurrentOperation.OperationId, CurrentOperation);
            }

            //Sets the new operation, which is automatically set to dragging state
            CurrentOperation = newOperation;

            if (currentInputClient.IsLocalhost)
            {
                ddManager.DoDragDrop(CurrentOperation.OperationData, newOperation.OperationId);
            }
            else
            {
                currentInputClient.SendDragDropData(CurrentOperation.OperationData.ToBytes(), CurrentOperation.OperationId);
            }
        }
Пример #3
0
        private Guid CreateTokenForOperationLocal(DataOperation operation, int timeout)
        {
            Guid accessId = Guid.NewGuid();

            ClipboardVirtualFileData file = operation.Data as ClipboardVirtualFileData;

            Guid[]   fIds     = new Guid[file.AllFiles.Count];
            string[] fSources = new string[file.AllFiles.Count];

            for (int i = 0; i < file.AllFiles.Count; i++)
            {
                fIds[i]     = file.AllFiles[i].FileRequestId;
                fSources[i] = file.AllFiles[i].FullPath;
            }

            return(CreateFileReadTokenForGroup(new FileAccessController.FileAccessInfo(fIds, fSources), timeout));
        }
        /// <summary>
        /// Converts a window dataobject to an inputshare clipboard data object
        /// </summary>
        /// <param name="data"></param>
        /// <param name="attempt"></param>
        /// <returns></returns>
        public static ClipboardDataBase ConvertToGeneric(System.Windows.Forms.IDataObject data, int attempt = 0)
        {
            try
            {
                System.Windows.Forms.DataObject obj = data as System.Windows.Forms.DataObject;
                if (data.GetDataPresent(DataFormats.Bitmap, true))
                {
                    using (Image i = obj.GetImage())
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            i.Save(ms, ImageFormat.Jpeg);
                            return(new ClipboardImageData(ms.ToArray(), true));
                        }
                    }
                }
                else if (data.GetDataPresent(DataFormats.Text))
                {
                    return(new ClipboardTextData((string)data.GetData(DataFormats.Text)));
                }
                else if (data.GetDataPresent(DataFormats.FileDrop))
                {
                    ClipboardVirtualFileData fd = ReadFileDrop(data);
                    return(fd);
                }

                else
                {
                    ISLogger.Write("Debug: Could not translate dataobject: type is not implemented");
                    return(null);
                }
            }
            catch (COMException ex)
            {
                ISLogger.Write("COM exception: " + ex.Message);
                Thread.Sleep(25);
                if (attempt > 10)
                {
                    throw new Exception("Could not read clipboard after 10 attempts.");
                }

                int n = attempt + 1;
                return(ConvertToGeneric(data, n));
            }
        }
Пример #5
0
        private Guid GenerateLocalAccessTokenForOperation(DragDropOperation operation)
        {
            if (operation.DataType != ClipboardDataType.File)
            {
                throw new ArgumentException("DateType must be file");
            }

            ClipboardVirtualFileData file = operation.OperationData as ClipboardVirtualFileData;

            Guid[]   fIds     = new Guid[file.AllFiles.Count];
            string[] fSources = new string[file.AllFiles.Count];

            for (int i = 0; i < file.AllFiles.Count; i++)
            {
                fIds[i]     = file.AllFiles[i].FileRequestId;
                fSources[i] = file.AllFiles[i].FullPath;
            }

            return(fileController.CreateFileReadTokenForGroup(new FileAccessController.FileAccessInfo(fIds, fSources), 10000));
        }
Пример #6
0
        public override void SetClipboardData(ClipboardDataBase data)
        {
            InputshareDataObject obj = new InputshareDataObject(data, false);

            if (data.DataType == ClipboardDataType.File)
            {
                //If two applications paste data, we can't know which of the two we are interacting with.
                //In other words, we don't know if its program A or program B calling GetData() on the InputshareDataObject
                //this means that files will just be corrupted if two programs try to paste the data

                //To fix this, as soon as the data is pasted, we put another InputshareDataObject onto the clipboard.
                //Each dataobject gets their own access token from the host to allow them to have seperate filestreams
                //and allow any number of programs to paste at the same time
                currentClipboardFiles = data as ClipboardVirtualFileData;
                obj.FilesPasted      += Obj_ObjectPasted;
            }


            cbHookWindow.SetClipboardData(obj);
        }
Пример #7
0
        public static void WriteFolderStructure(ClipboardVirtualFileData data, string rootDir)
        {
            if (!Directory.Exists(rootDir))
            {
                Directory.CreateDirectory(rootDir);
            }

            foreach (var rootFolder in data.RootDirectory.SubFolders)
            {
                if (!Directory.Exists(Path.Combine(rootDir, rootFolder.Name)))
                {
                    Directory.CreateDirectory(Path.Combine(rootDir, rootFolder.Name));
                }

                foreach (var file in rootFolder.Files)
                {
                    File.Create(Path.Combine(rootDir, rootFolder.Name, file.FileName)).Dispose();
                }
            }

            WriteRecursive(data.RootDirectory, rootDir);
        }
        private async void SetClipboardFiles(ClipboardVirtualFileData cbFiles, ISServerSocket host, Guid operationId)
        {
            if (currentOperation != null && currentOperation.DataType == ClipboardDataType.File)
            {
                previousOperationDictionary.Add(currentOperation.OperationId, currentOperation);
            }

            currentOperation = new ClipboardOperation(operationId, cbFiles.DataType, cbFiles, host);
            if (host == ISServerSocket.Localhost)
            {
                //TODO - We can't use the same access token for clipboard operations, as more than one client can
                //be reading from the stream at the same time which will cause corruption.
                //We need to create a new access token for each client that pastes the files to create multiple stream instances
            }
            else
            {
                //Assign virtual file events, so if localhosts pastes the files then the shell can read data from the host.
                foreach (var file in cbFiles.AllFiles)
                {
                    file.ReadComplete += File_ReadComplete;
                    file.ReadDelegate  = File_RequestDataAsync;
                }

                //Create a token so that localhost can access files

                try
                {
                    currentOperation.LocalhostAccessToken = await currentOperation.Host.RequestFileTokenAsync(operationId);
                }catch (Exception ex)
                {
                    ISLogger.Write("GlobalClipboardController: Failed to get access token for clipboard content: " + ex.Message);
                    return;
                }
            }

            BroadcastCurrentOperation();
        }
Пример #9
0
 /// <summary>
 /// Creates an IStream that uses a network machine as the source of data
 /// </summary>
 /// <param name="file"></param>
 internal ManagedRemoteIStream(FileAttributes file, ClipboardVirtualFileData parent, Guid accessToken)
 {
     sourceClipboardData = parent;
     this.accessToken    = accessToken;
     SourceVirtualFile   = file;
 }
Пример #10
0
        public InputshareDataObject(ClipboardDataBase data, bool isDragDrop)
        {
            isDragDropData = isDragDrop;
            OperationGuid  = data.OperationId;

            supportedFormats.Add(new FORMATETC
            {
                cfFormat = (short)InputshareClipboardFormatId,
                dwAspect = DVASPECT.DVASPECT_CONTENT,
                lindex   = -1,
                ptd      = IntPtr.Zero,
                tymed    = TYMED.TYMED_HGLOBAL
            });

            if (data is ClipboardTextData cbText)
            {
                supportedFormats.Add(new FORMATETC
                {
                    cfFormat = formatTextId,
                    dwAspect = DVASPECT.DVASPECT_CONTENT,
                    lindex   = -1,
                    ptd      = IntPtr.Zero,
                    tymed    = TYMED.TYMED_HGLOBAL
                });

                ISLogger.Write("Stored text = " + cbText.Text);
                storedText = cbText.Text;
            }
            else if (data is ClipboardVirtualFileData cbFiles)
            {
                storedFiles = cbFiles;

                supportedFormats.Add(new FORMATETC
                {
                    cfFormat = formatFileContentsId,
                    dwAspect = DVASPECT.DVASPECT_CONTENT,
                    lindex   = -1,
                    ptd      = IntPtr.Zero,
                    tymed    = TYMED.TYMED_ISTREAM
                });

                supportedFormats.Add(new FORMATETC
                {
                    cfFormat = formatFileDescriptorId,
                    dwAspect = DVASPECT.DVASPECT_CONTENT,
                    lindex   = -1,
                    ptd      = IntPtr.Zero,
                    tymed    = TYMED.TYMED_HGLOBAL
                });

                supportedFormats.Add(new FORMATETC
                {
                    cfFormat = (short)DataFormats.GetFormat("Preferred DropEffect").Id,
                    dwAspect = DVASPECT.DVASPECT_CONTENT,
                    lindex   = -1,
                    ptd      = IntPtr.Zero,
                    tymed    = TYMED.TYMED_HGLOBAL
                });
            }
            else if (data is ClipboardImageData cbImage)
            {
                using (MemoryStream ms = new MemoryStream(cbImage.ImageData))
                {
                    storedImage = (Bitmap)Image.FromStream(ms);
                }

                supportedFormats.Add(new FORMATETC
                {
                    cfFormat = formatBitmapId,
                    dwAspect = DVASPECT.DVASPECT_CONTENT,
                    lindex   = -1,
                    ptd      = IntPtr.Zero,
                    tymed    = TYMED.TYMED_GDI
                });
            }
        }