// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package rdpclient.clip; import streamer.BaseElement; import streamer.ByteBuffer; import streamer.Link; public class ServerClipRdrChannelRouter extends BaseElement { /** * Key for ASCII names message flag in payload metadata. Value is Boolean. */ public static final String ASCII_NAMES = "ascii_names"; /** * Key for success/fail message flag in payload metadata. Value is Boolean. */ public static final String SUCCESS = "success"; /** * Monitor Ready PDU */ public static final int CB_MONITOR_READY = 0x0001; /** * Format List PDU */ public static final int CB_FORMAT_LIST = 0x0002; /** * Format List Response PDU */ public static final int CB_FORMAT_LIST_RESPONSE = 0x0003; /** * Format Data Request PDU */ public static final int CB_FORMAT_DATA_REQUEST = 0x0004; /** * Format Data Response PDU */ public static final int CB_FORMAT_DATA_RESPONSE = 0x0005; /** * Temporary Directory PDU */ public static final int CB_TEMP_DIRECTORY = 0x0006; /** * Clipboard Capabilities PDU */ public static final int CB_CLIP_CAPS = 0x0007; /** * File Contents Request PDU */ public static final int CB_FILECONTENTS_REQUEST = 0x0008; /** * File Contents Response PDU */ public static final int CB_FILECONTENTS_RESPONSE = 0x0009; /** * Lock Clipboard Data PDU */ public static final int CB_LOCK_CLIPDATA = 0x000A; /** * Unlock Clipboard Data PDU */ public static final int CB_UNLOCK_CLIPDATA = 0x000B; /** * Used by the Format List Response PDU, Format Data Response PDU, and File * Contents Response PDU to indicate that the associated request Format List * PDU, Format Data Request PDU, and File Contents Request PDU were processed * successfully. */ public static final int CB_RESPONSE_OK = 0x0001; /** * Used by the Format List Response PDU, Format Data Response PDU, and File * Contents Response PDU to indicate that the associated Format List PDU, * Format Data Request PDU, and File Contents Request PDU were not processed * successfully. */ public static final int CB_RESPONSE_FAIL = 0x0002; /** * Used by the Short Format Name variant of the Format List Response PDU to * indicate the format names are in ASCII 8. */ public static final int CB_ASCII_NAMES = 0x0004; public ServerClipRdrChannelRouter(String id) { super(id); } @Override public void handleData(ByteBuffer buf, Link link) { if (verbose) System.out.println("[" + this + "] INFO: Data received: " + buf + "."); // Parse PDU header // Example: 07 00 -> CLIPRDR_HEADER::msgType = CB_CLIP_CAPS (7) int msgType = buf.readUnsignedShortLE(); // Example: 00 00 -> CLIPRDR_HEADER::msgFlags = 0 int msgFlags = buf.readUnsignedShortLE(); // Example: 10 00 00 00 -> CLIPRDR_HEADER::dataLen = 0x10 = 16 bytes long dataLenLong = buf.readSignedIntLE(); if (dataLenLong > 4 * 1024 * 1024) throw new RuntimeException("Clipboard packet is too long. Expected length: less than 4MiB. Actual length: " + dataLenLong + "."); int dataLen = (int)dataLenLong; ByteBuffer payload = buf.readBytes(dataLen); // Parse message flags and store them in the payload metadata if ((msgFlags & CB_RESPONSE_OK) == CB_RESPONSE_OK) payload.putMetadata("success", true); if ((msgFlags & CB_RESPONSE_FAIL) == CB_RESPONSE_FAIL) payload.putMetadata(SUCCESS, false); if ((msgFlags & CB_ASCII_NAMES) == CB_ASCII_NAMES) payload.putMetadata(ASCII_NAMES, true); // Push PDU to appropriate handler switch (msgType) { case CB_MONITOR_READY: pushDataToPad("monitor_ready", payload); break; case CB_FORMAT_LIST: pushDataToPad("format_list", payload); break; case CB_FORMAT_LIST_RESPONSE: pushDataToPad("format_list_response", payload); break; case CB_FORMAT_DATA_REQUEST: pushDataToPad("format_data_request", payload); break; case CB_FORMAT_DATA_RESPONSE: pushDataToPad("format_data_response", payload); break; case CB_TEMP_DIRECTORY: throw new RuntimeException("[" + this + "] ERROR: Unexpected clipboard temporary directory PDU received from server. Data: " + buf + "."); case CB_CLIP_CAPS: pushDataToPad("clipboard_capabilities", payload); break; case CB_FILECONTENTS_REQUEST: pushDataToPad("filecontent_request", payload); break; case CB_FILECONTENTS_RESPONSE: pushDataToPad("filecontent_response", payload); break; case CB_LOCK_CLIPDATA: pushDataToPad("lock_clipdata", payload); break; case CB_UNLOCK_CLIPDATA: pushDataToPad("unlock_clipdata", payload); break; default: throw new RuntimeException("[" + this + "] ERROR: Unknown clipboard PDU message type: " + msgType + "."); } buf.unref(); } /** * Example. */ public static void main(String args[]) { // TODO } }