blob: 32381247ff8a888cb3008fed2e6129cf075fc9aa [file] [log] [blame]
// 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
}
}