⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clipchannel.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
字号:
/* ClipChannel.java
 * Component: ProperJavaRDP
 * 
 * Revision: $Revision: 1.4 $
 * Author: $Author: telliott $
 * Date: $Date: 2005/09/27 14:15:40 $
 *
 * Copyright (c) 2005 Propero Limited
 *
 * Purpose: 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * 
 * (See gpl.txt for details of the GNU General Public License.)
 * 
 */
package net.propero.rdp.rdp5.cliprdr;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.IOException;
import java.util.Iterator;

import org.apache.log4j.Logger;

import net.propero.rdp.CommunicationMonitor;
import net.propero.rdp.Constants;
import net.propero.rdp.Input;
import net.propero.rdp.Common;
import net.propero.rdp.Options;
import net.propero.rdp.RdesktopException;
import net.propero.rdp.RdpPacket;
import net.propero.rdp.RdpPacket_Localised;
import net.propero.rdp.Secure;
import net.propero.rdp.crypto.CryptoException;
import net.propero.rdp.rdp5.VChannel;
import net.propero.rdp.rdp5.VChannels;

public class ClipChannel extends VChannel implements ClipInterface, ClipboardOwner, FocusListener {

	String[] types = {
			"unused",
			"CF_TEXT",
			"CF_BITMAP",
			"CF_METAFILEPICT",
			"CF_SYLK",
			"CF_DIF",
			"CF_TIFF",
			"CF_OEMTEXT",
			"CF_DIB",
			"CF_PALETTE",
			"CF_PENDATA",
			"CF_RIFF",
			"CF_WAVE",
			"CF_UNICODETEXT",
			"CF_ENHMETAFILE",
			"CF_HDROP",
			"CF_LOCALE",
			"CF_MAX"
	};
	
	protected static Logger logger = Logger.getLogger(Input.class);
		
	// Message types
	public static final int CLIPRDR_CONNECT = 1;
	public static final int CLIPRDR_FORMAT_ANNOUNCE = 2;
	public static final int CLIPRDR_FORMAT_ACK = 3;
	public static final int CLIPRDR_DATA_REQUEST = 4;
	public static final int CLIPRDR_DATA_RESPONSE = 5;

	// Message status codes
	public static final int CLIPRDR_REQUEST = 0;
	public static final int CLIPRDR_RESPONSE = 1;
	public static final int CLIPRDR_ERROR = 2;

	Clipboard clipboard;

	// TypeHandler for data currently being awaited
	TypeHandler currentHandler = null;
	// All type handlers available
	TypeHandlerList allHandlers = null;
	byte[] localClipData = null;
	
	public ClipChannel(){
		this.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
		
		// initialise all clipboard format handlers
		allHandlers = new TypeHandlerList();
		allHandlers.add(new UnicodeHandler());
		allHandlers.add(new TextHandler());
		allHandlers.add(new DIBHandler());
		//allHandlers.add(new MetafilepictHandler());
	}
	
	/* 
	 * VChannel inherited abstract methods
	 */
	public String name() {
		return "cliprdr";
	}

	public int flags() {
		return VChannels.CHANNEL_OPTION_INITIALIZED | VChannels.CHANNEL_OPTION_ENCRYPT_RDP |
		 VChannels.CHANNEL_OPTION_COMPRESS_RDP | VChannels.CHANNEL_OPTION_SHOW_PROTOCOL;
	}
	
	/*
	 * Data processing methods
	 */	
	public void process(RdpPacket data) throws RdesktopException, IOException, CryptoException {

		int type, status;
		int length, format;

		type = data.getLittleEndian16();
		status = data.getLittleEndian16();
		length = data.getLittleEndian32();
			
		if (status == CLIPRDR_ERROR)
		{
			if (type == CLIPRDR_FORMAT_ACK)
			{
				send_format_announce();
				return;
			}

			return;
		}
		
		switch (type)
		{
			case CLIPRDR_CONNECT:
				send_format_announce();
				break;
			case CLIPRDR_FORMAT_ANNOUNCE:
				handle_clip_format_announce(data, length);
				return;
			case CLIPRDR_FORMAT_ACK:
				break;
			case CLIPRDR_DATA_REQUEST:
				handle_data_request(data);
				break;
			case CLIPRDR_DATA_RESPONSE:
				handle_data_response(data, length);
				break;
			case 7:
				break;
			default:
				//System.out.println("Unimplemented packet type! " + type);
		}
		

	}
	
	public void
	send_null(int type, int status)
	{
		RdpPacket_Localised s;

		s = new RdpPacket_Localised(12);
		s.setLittleEndian16(type);
		s.setLittleEndian16(status);
		s.setLittleEndian32(0);
		s.setLittleEndian32(0); // pad
		s.markEnd();
		
		try {
			this.send_packet(s);
		} catch (RdesktopException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		} catch (CryptoException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
		}
	}
	
	void send_format_announce() throws RdesktopException, IOException, CryptoException{
		Transferable clipData	=	clipboard.getContents(clipboard);
		DataFlavor[] dataTypes = clipData.getTransferDataFlavors();
		
		TypeHandlerList availableFormats = allHandlers.getHandlersForClipboard(dataTypes);
		
		RdpPacket_Localised s;
		int number_of_formats = availableFormats.count();
		
		s = new RdpPacket_Localised(number_of_formats * 36 + 12);
		s.setLittleEndian16(CLIPRDR_FORMAT_ANNOUNCE);
		s.setLittleEndian16(CLIPRDR_REQUEST);
		s.setLittleEndian32(number_of_formats * 36);
		
		TypeHandler handler = null;
		for(Iterator i = availableFormats.iterator(); i.hasNext();){
			handler = (TypeHandler) i.next();
			s.setLittleEndian32(handler.preferredFormat());
			s.incrementPosition(32);
		}
		
		s.setLittleEndian32(0); // pad
		s.markEnd();
		send_packet(s);
	}
		
	private void handle_clip_format_announce(RdpPacket data, int length) throws RdesktopException, IOException, CryptoException {
		TypeHandlerList serverTypeList = new TypeHandlerList();
		
		//System.out.print("Available types: ");
		for(int c = length; c >= 36; c-=36){
			int typeCode = data.getLittleEndian32();
			//if(typeCode < types.length) System.out.print(types[typeCode] + " ");
			data.incrementPosition(32);
			serverTypeList.add(allHandlers.getHandlerForFormat(typeCode));
		}
		//System.out.println();
				
		send_null(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE);
		currentHandler = serverTypeList.getFirst();
		
		if(currentHandler != null) request_clipboard_data(currentHandler.preferredFormat());
	}
	
	void handle_data_request(RdpPacket data) throws RdesktopException, IOException, CryptoException
	{
		int format = data.getLittleEndian32();
		Transferable clipData = clipboard.getContents(this);
		byte[] outData = null;
		
		TypeHandler outputHandler = allHandlers.getHandlerForFormat(format);
		if(outputHandler != null){
			outputHandler.send_data(clipData, this);
			// outData = outputHandler.fromTransferable(clipData);
			//if(outData != null){
			//	send_data(outData,outData.length);
			//	return;
			//}
			//else System.out.println("Clipboard data to send == null!");
		}

		//this.send_null(CLIPRDR_DATA_RESPONSE,CLIPRDR_ERROR);
	}

	void
	handle_data_response(RdpPacket data, int length)
	{
		//if(currentHandler != null)clipboard.setContents(currentHandler.handleData(data, length),this);
		//currentHandler = null;
		if(currentHandler != null) currentHandler.handleData(data, length, this);
		currentHandler = null;
	}
	
	void request_clipboard_data(int formatcode)throws RdesktopException,IOException,CryptoException{
	
		RdpPacket_Localised s = Common.secure.init(Constants.encryption ? Secure.SEC_ENCRYPT : 0, 24);
		s.setLittleEndian32(16); // length
		
		int flags = VChannels.CHANNEL_FLAG_FIRST | VChannels.CHANNEL_FLAG_LAST;
		if ((this.flags() & VChannels.CHANNEL_OPTION_SHOW_PROTOCOL) != 0) flags |= VChannels.CHANNEL_FLAG_SHOW_PROTOCOL;
		
		s.setLittleEndian32(flags);
		s.setLittleEndian16(CLIPRDR_DATA_REQUEST);
		s.setLittleEndian16(CLIPRDR_REQUEST);
		s.setLittleEndian32(4); // Remaining length
		s.setLittleEndian32(formatcode);
		s.setLittleEndian32(0); // Unknown. Garbage pad?
		s.markEnd();
		
		Common.secure.send_to_channel(s, Constants.encryption ? Secure.SEC_ENCRYPT : 0, this.mcs_id());
	}
	
	public void
	send_data(byte []data, int length)
	{
		CommunicationMonitor.lock(this);
				
		RdpPacket_Localised all = new RdpPacket_Localised(12 + length);
		
		all.setLittleEndian16(CLIPRDR_DATA_RESPONSE);
		all.setLittleEndian16(CLIPRDR_RESPONSE);
		all.setLittleEndian32(length+4);	// don't know why, but we need to add between 1 and 4 to the length, 
											// otherwise the server cliprdr thread hangs
		all.copyFromByteArray(data,0,all.getPosition(),length);
		all.incrementPosition(length);
		all.setLittleEndian32(0);
		
		try {
			this.send_packet(all);
		} catch (RdesktopException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
            if(!Common.underApplet) System.exit(-1);
		} catch (IOException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
            if(!Common.underApplet) System.exit(-1);
		} catch (CryptoException e) {
			System.err.println(e.getMessage());
			e.printStackTrace();
            if(!Common.underApplet) System.exit(-1);
		}
		
		CommunicationMonitor.unlock(this);
	}
	
	/*
	 * FocusListener methods
	 */
	public void focusGained(FocusEvent arg0) {
		// synchronise the clipboard types here, so the server knows what's available	
		if(Options.use_rdp5){
			try { send_format_announce(); } 
			catch (RdesktopException e) {} 
			catch (IOException e) {}
			catch (CryptoException e) {}
		}
	}

	public void focusLost(FocusEvent arg0) {}

	/*
	 * Support methods
	 */
	private void reset_bool(boolean[] x){
		for(int i = 0; i < x.length; i++) x[i] = false;
	}
	
	/*
	 * ClipboardOwner methods
	 */
	public void lostOwnership(Clipboard arg0, Transferable arg1) {
		logger.debug("Lost clipboard ownership");
	}

	public void copyToClipboard(Transferable t) {
		clipboard.setContents(t,this);
	}

	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -