| // 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.rdp; | |
| import streamer.BaseElement; | |
| import streamer.ByteBuffer; | |
| import streamer.Element; | |
| import streamer.Link; | |
| import streamer.Pipeline; | |
| import streamer.PipelineImpl; | |
| import streamer.debug.MockSink; | |
| import streamer.debug.MockSource; | |
| import common.ScreenDescription; | |
| /** | |
| * @see <a href="http://msdn.microsoft.com/en-us/library/cc240488.aspx">microsoft msdn explanation</a> | |
| */ | |
| public class ClientConfirmActivePDU extends BaseElement { | |
| public static final String SOURCE_DESC = "MSTSC"; | |
| public static final int CAPSTYPE_BITMAP = 0x2; | |
| protected int numberCapabilities; | |
| protected RdpState state; | |
| protected ScreenDescription screen; | |
| protected boolean desktopResize = false; | |
| protected int prefferedBitsPerPixel = 16; | |
| public ClientConfirmActivePDU(String id, ScreenDescription screen, RdpState state) { | |
| super(id); | |
| this.state = state; | |
| this.screen = screen; | |
| } | |
| @Override | |
| public void handleData(ByteBuffer aBuf, Link link) { | |
| // Body | |
| ByteBuffer buf = new ByteBuffer(1024, true); | |
| numberCapabilities = 0; | |
| writeCapabilities(buf); | |
| buf.trimAtCursor(); | |
| // Header | |
| ByteBuffer header = createMCSHeader(buf); | |
| // Length of source descriptor, including NULL character (LE) | |
| header.writeShortLE(SOURCE_DESC.length() + 1); | |
| // Length of combined capabilities + 4 bytes (number of capabilities and | |
| // padding) (LE) | |
| header.writeShortLE(buf.length + 4); | |
| header.writeString(SOURCE_DESC, RdpConstants.CHARSET_8); | |
| header.writeByte(0); | |
| // Number of capabilities | |
| header.writeShortLE(numberCapabilities); | |
| // Padding 2 bytes | |
| header.writeShortLE(0); | |
| header.trimAtCursor(); | |
| // Prepend header to capabilities | |
| buf.prepend(header); | |
| // Trim buffer to actual length of data written | |
| buf.trimAtCursor(); | |
| pushDataToPad(STDOUT, buf); | |
| sendOtherRequredPackets(); | |
| } | |
| private ByteBuffer createMCSHeader(ByteBuffer buf) { | |
| ByteBuffer header = new ByteBuffer(100); | |
| // MCS Send Data Request | |
| header.writeByte(0x64); | |
| // Initiator: 1004 (1001+3) | |
| header.writeShort(3); | |
| // Channel ID: 1003 (I/O channel) | |
| header.writeShort(RdpConstants.CHANNEL_IO); | |
| // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10) | |
| header.writeByte(0x70); | |
| int length = buf.length + 26; | |
| // User data length: (variable length field, LE) | |
| header.writeVariableShort(length); | |
| // Total length: (LE) | |
| header.writeShortLE(length); | |
| // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE) | |
| header.writeShortLE(0x13); | |
| // PDU source: 1004 (LE) | |
| header.writeShortLE(1004); | |
| // Share ID, e.g. 0x000103ea (LE) | |
| header.writeIntLE((int)state.serverShareId); | |
| // Originator ID: 1002 (LE) | |
| header.writeShortLE(1002); | |
| return header; | |
| } | |
| private void sendOtherRequredPackets() { | |
| // Send sequence in bulk | |
| sendSynchronizePDU(); | |
| sendControlPDUActionCooperate(); | |
| sendControlPDUActionRequestControl(); | |
| // sendBitmapCachePersistentListPDU(); | |
| sendFontListPDU(); | |
| } | |
| private void sendFontListPDU() { | |
| { | |
| int length = 1024; // Large enough | |
| ByteBuffer buf = new ByteBuffer(length, true); | |
| /* @formatter:off */ | |
| buf.writeBytes(new byte[] { | |
| // MCS Send Data Request | |
| (byte)0x64, | |
| // Initiator: 1004 (1001+3) | |
| (byte)0x00, (byte)0x03, | |
| // Channel ID: 1003 (I/O channel) | |
| (byte)0x03, (byte)0xeb, | |
| // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10) | |
| (byte)0x70, | |
| // User data length: 26 bytes (0x1a, variable length field) | |
| (byte)0x80, (byte)0x1a, | |
| // Total length: 26 bytes (0x1a, LE) | |
| (byte)0x1a, (byte)0x00, | |
| // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE) | |
| (byte)0x17, (byte)0x00, | |
| // PDU source: 1004 (LE) | |
| (byte)0xec, (byte)0x03, | |
| }); | |
| // Share ID, 4 bytes (LE) | |
| buf.writeIntLE((int)state.serverShareId); | |
| buf.writeBytes(new byte[] { | |
| // Padding 1 byte | |
| (byte)0x00, | |
| // Stream ID: STREAM_LOW (1) | |
| (byte)0x01, | |
| // uncompressedLength : 12 bytes (LE) | |
| (byte)0x0c, (byte)0x00, | |
| // pduType2: PDUTYPE2_FONTLIST (39) | |
| (byte)0x27, | |
| // generalCompressedType: 0 | |
| (byte)0x00, | |
| // generalCompressedLength: 0 (LE) | |
| (byte)0x00, (byte)0x00, | |
| // numberEntries (should be set to zero): 0 (LE) | |
| (byte)0x00, (byte)0x00, | |
| // totalNumEntries (should be set to zero): 0 (LE) | |
| (byte)0x00, (byte)0x00, | |
| // listFlags (should be set to 0x3): 0x0003 (LE), FONTLIST_LAST(0x2) | FONTLIST_FIRST(0x1) | |
| (byte)0x03, (byte)0x00, | |
| // entrySize: 50 bytes (0x0032, LE) | |
| (byte)0x32, (byte)0x00, | |
| }); | |
| /* @formatter:on */ | |
| // Trim buffer to actual length of data written | |
| buf.trimAtCursor(); | |
| pushDataToPad(STDOUT, buf); | |
| } | |
| } | |
| private void sendControlPDUActionRequestControl() { | |
| int length = 1024; // Large enough | |
| ByteBuffer buf = new ByteBuffer(length, true); | |
| /* @formatter:off */ | |
| buf.writeBytes(new byte[] { | |
| // MCS Send Data Request | |
| (byte)0x64, | |
| // Initiator: 1004 (1001+3) | |
| (byte)0x00, (byte)0x03, | |
| // Channel ID: 1003 (I/O channel) | |
| (byte)0x03, (byte)0xeb, | |
| // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10) | |
| (byte)0x70, | |
| // User data length: 26 bytes (0x1a, variable length field) | |
| (byte)0x80, (byte)0x1a, | |
| // Total length: 26 bytes (0x1a, LE) | |
| (byte)0x1a, (byte)0x00, | |
| // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE) | |
| (byte)0x17, (byte)0x00, | |
| // PDU source: 1004 (LE) | |
| (byte)0xec, (byte)0x03, | |
| }); | |
| // Share ID, 4 bytes (LE) | |
| buf.writeIntLE((int)state.serverShareId); | |
| buf.writeBytes(new byte[] { | |
| // Padding 1 byte | |
| (byte)0x00, | |
| // Stream ID: STREAM_LOW (1) | |
| (byte)0x01, | |
| // uncompressedLength : 12 bytes (LE) | |
| (byte)0x0c, (byte)0x00, | |
| // pduType2: PDUTYPE2_CONTROL (20) | |
| (byte)0x14, | |
| // generalCompressedType: 0 | |
| (byte)0x00, | |
| // generalCompressedLength: 0 (LE) | |
| (byte)0x00, (byte)0x00, | |
| // action: CTRLACTION_REQUEST_CONTROL (1) (LE) | |
| (byte)0x01, (byte)0x00, | |
| // grantId: 0 (LE) | |
| (byte)0x00, (byte)0x00, | |
| // controlId: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| }); | |
| /* @formatter:on */ | |
| // Trim buffer to actual length of data written | |
| buf.trimAtCursor(); | |
| pushDataToPad(STDOUT, buf); | |
| } | |
| private void sendControlPDUActionCooperate() { | |
| int length = 1024; // Large enough | |
| ByteBuffer buf = new ByteBuffer(length, true); | |
| /* @formatter:off */ | |
| buf.writeBytes(new byte[] { | |
| // MCS Send Data Request | |
| (byte)0x64, | |
| // Initiator: 1004 (1001+3) | |
| (byte)0x00, (byte)0x03, | |
| // Channel ID: 1003 (I/O channel) | |
| (byte)0x03, (byte)0xeb, | |
| // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10) | |
| (byte)0x70, | |
| // User data length: 26 bytes (0x1a, variable length field) | |
| (byte)0x80, (byte)0x1a, | |
| // Total length: 26 bytes (0x1a, LE) | |
| (byte)0x1a,(byte)0x00, | |
| // PDU type: PDUTYPE_DATAPDU (0x7), PDU version: 1 (0x0010) (LE) | |
| (byte)0x17, (byte)0x00, | |
| // PDU source: 1004 (LE) | |
| (byte)0xec, (byte)0x03, | |
| }); | |
| // Share ID, 4 bytes (LE) | |
| buf.writeIntLE((int)state.serverShareId); | |
| buf.writeBytes(new byte[] { | |
| // Padding 1 byte | |
| (byte)0x00, | |
| // Stream ID: STREAM_LOW (1) | |
| (byte)0x01, | |
| // uncompressedLength : 12 bytes (LE) | |
| (byte)0x0c, (byte)0x00, | |
| // pduType2: PDUTYPE2_CONTROL (20) | |
| (byte)0x14, | |
| // generalCompressedType: 0 | |
| (byte)0x00, | |
| // generalCompressedLength: 0 (LE?) | |
| (byte)0x00, (byte)0x00, | |
| // action: CTRLACTION_COOPERATE (4) (LE) | |
| (byte)0x04, (byte)0x00, | |
| // grantId: 0 (LE) | |
| (byte)0x00, (byte)0x00, | |
| // controlId: 0 | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| }); | |
| /* @formatter:on */ | |
| buf.trimAtCursor(); | |
| pushDataToPad(STDOUT, buf); | |
| } | |
| private void sendSynchronizePDU() { | |
| ByteBuffer buf = new ByteBuffer(1024, true); | |
| /* @formatter:off */ | |
| buf.writeBytes(new byte[] { | |
| // MCS send data request | |
| (byte)0x64, | |
| // Initiator: 1004 (1001+3) | |
| (byte)0x00, (byte)0x03, | |
| // Channel ID: 1003 (I/O Channel) | |
| (byte)0x03, (byte)0xeb, | |
| // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10) | |
| (byte)0x70, | |
| // Data length: 22 bytes (0x16, variable length field) | |
| (byte)0x80, (byte)0x16, | |
| // RDP: total length: 22 bytes (LE) | |
| (byte)0x16, (byte)0x00, | |
| // PDU type: PDUTYPE_DATAPDU (0x7), TS_PROTOCOL_VERSION (0x10) (LE) | |
| (byte)0x17, (byte)0x00, | |
| // PDU source: 1007 (LE) | |
| (byte)0xec, (byte)0x03, | |
| }); | |
| // Share ID, 4 bytes (LE) | |
| buf.writeIntLE((int)state.serverShareId); | |
| buf.writeBytes(new byte[] { | |
| // Padding: 1 byte | |
| (byte)0x00, | |
| // Stream ID: STREAM_LOW (1) | |
| (byte)0x01, | |
| // uncompressedLength : 8 bytes (LE) | |
| (byte)0x08, (byte)0x00, | |
| // pduType2 = PDUTYPE2_SYNCHRONIZE (31) | |
| (byte)0x1f, | |
| // generalCompressedType: 0 | |
| (byte)0x00, | |
| // generalCompressedLength: 0 (LE?) | |
| (byte)0x00, (byte)0x00, | |
| // messageType: SYNCMSGTYPE_SYNC (1) (LE) | |
| (byte)0x01, (byte)0x00, | |
| // targetUser: 0x03ea | |
| (byte)0xea, (byte)0x03, | |
| }); | |
| /* @formatter:on */ | |
| buf.trimAtCursor(); | |
| pushDataToPad(STDOUT, buf); | |
| } | |
| private void writeCapabilities(ByteBuffer buf) { | |
| writeGeneralCS(buf); | |
| writeBitmapCS(buf); | |
| writeOrderCS(buf); | |
| writeBitmapCache2CS(buf); | |
| writeColorTableCacheCS(buf); | |
| writeWindowActivationCS(buf); | |
| writeControlCS(buf); | |
| writePointerCS(buf); | |
| writeShareCS(buf); | |
| writeInputCS(buf); | |
| writeBrushCS(buf); | |
| writeSoundCS(buf); | |
| writeFontCS(buf); | |
| writeOffscreenBitmapCS(buf); | |
| writeGlyphCacheCS(buf); | |
| } | |
| private void writeBrushCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Brush Capability Set (8 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240564.aspx | |
| (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15, | |
| // LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel: | |
| // BRUSH_DEFAULT | |
| // (0x0, LE) | |
| }); | |
| } | |
| private void writeInputCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Input Capability Set (88 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240563.aspx | |
| (byte)0x0d, | |
| (byte)0x00, // capability set type: CAPSTYPE_INPUT (13, LE) | |
| (byte)0x58, | |
| (byte)0x00, // length of capability set: 88 bytes (LE) | |
| (byte)0x35, | |
| (byte)0x00, // inputFlags: 0x0035 (LE), INPUT_FLAG_FASTPATH_INPUT2 | |
| // (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX | |
| // (0x4), INPUT_FLAG_SCANCODES (0x1) | |
| (byte)0x00, | |
| (byte)0x00, // Padding 2 bytes | |
| (byte)0x09, | |
| (byte)0x04, | |
| (byte)0x00, | |
| (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE) | |
| (byte)0x00, | |
| (byte)0x00, | |
| (byte)0x00, | |
| (byte)0x00, // keyboardType: unknown (LE) | |
| (byte)0x00, | |
| (byte)0x00, | |
| (byte)0x00, | |
| (byte)0x00, // keyboardSubType: unknown (LE) | |
| (byte)0x00, | |
| (byte)0x00, | |
| (byte)0x00, | |
| (byte)0x00, // keyboardFunctionKey: unknown (LE) | |
| // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| }); | |
| } | |
| private void writeShareCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Share Capability Set (8 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240570.aspx | |
| (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes (LE) | |
| }); | |
| } | |
| private void writePointerCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Pointer Capability Set (10 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240562.aspx | |
| (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8, | |
| // LE) | |
| (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE) | |
| (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE) | |
| (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE) | |
| (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE) | |
| }); | |
| } | |
| private void writeControlCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Control Capability Set (12 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240568.aspx | |
| (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION | |
| // (7) | |
| (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE) | |
| (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE) | |
| (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0 | |
| // (LE) | |
| (byte)0x02, (byte)0x00, // controlInterest (should be set to | |
| // CONTROLPRIORITY_NEVER): | |
| // CONTROLPRIORITY_NEVER (2) (LE) | |
| (byte)0x02, (byte)0x00, // detachInterest (should be set to | |
| // CONTROLPRIORITY_NEVER): | |
| // CONTROLPRIORITY_NEVER (2) (LE) | |
| }); | |
| } | |
| private void writeWindowActivationCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Window Activation Capability Set (12 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240569.aspx | |
| (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION | |
| // (7) (LE) | |
| (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE) | |
| (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)): | |
| // FALSE (0, LE) | |
| (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE | |
| // (0)): FALSE (0, LE) | |
| (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE | |
| // (0)): FALSE (0, LE) | |
| (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to | |
| // FALSE (0)): FALSE (0, LE) | |
| }); | |
| } | |
| private void writeColorTableCacheCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Color Table Cache Capability Set (8 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc241564.aspx | |
| (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE | |
| // (10) (LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x06, (byte)0x00, // Color table cache size (must be ignored | |
| // during capability exchange and is assumed | |
| // to be 0x0006): 6 (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| }); | |
| } | |
| private void writeBitmapCache2CS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Bitmap Cache Rev. 2 Capability Set (40 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240560.aspx | |
| (byte)0x13, (byte)0x00, // capability set type: | |
| // CAPSTYPE_BITMAPCACHE_REV2 (19) (LE) | |
| (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE) | |
| (byte)0x00, (byte)0x00, // Cache flags: 0 (LE) | |
| (byte)0x00, // Padding 1 byte | |
| (byte)0x00, // Number of cell caches: 0 | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0 | |
| // cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1 | |
| // cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2 | |
| // cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3 | |
| // cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4 | |
| // cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding | |
| }); | |
| } | |
| private void writeGeneralCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // Capabilities, see | |
| // http://msdn.microsoft.com/en-us/library/cc240486.aspx | |
| // | |
| // General capability set (24 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240549.aspx | |
| (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1) | |
| // (LE) | |
| (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE) | |
| (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE) | |
| (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE) | |
| (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE) | |
| // Extra flags: 0x040d (LE) | |
| // FastPathOutput: (...............1) Advertiser supports fast-path | |
| // output | |
| // ShadowCompression: (..............0.) Advertiser NOT supports shadow | |
| // compression | |
| // LongLengthCredentials: (.............1..) Advertiser supports | |
| // long-length credentials for the user name, password, or domain name | |
| // SessionAutoreconnection: (............1...) Advertiser supports | |
| // session auto-reconnection | |
| // ImprovedEncryptionChecksum: (...........0....) Client and server NOT | |
| // support improved encryption checksum | |
| // Reserved1: (......00000.....) | |
| // CompressedBitMapDataFlag: (.....1..........) No 8-UINT8 header is | |
| // present for compressed bitmap data | |
| // Reserved2: (00000...........) | |
| (byte)0x0d, (byte)0x04, | |
| (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE) | |
| (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE) | |
| (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE) | |
| (byte)0x00, // refreshRectSupport: FALSE (0) | |
| (byte)0x00, // suppressOutputSupport: FALSE (0) | |
| }); | |
| } | |
| private void writeBitmapCS(ByteBuffer buf) { | |
| // Bitmap capability set (28 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240554.aspx | |
| numberCapabilities++; | |
| // Capability set type: CAPSTYPE_BITMAP (2) (LE) | |
| buf.writeShortLE(CAPSTYPE_BITMAP); | |
| // Length of capability set: 28 bytes (LE) | |
| buf.writeShortLE(28); | |
| // preferredBitsPerPixel: 16 bpp (LE) | |
| buf.writeShortLE(prefferedBitsPerPixel); | |
| // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| buf.writeShortLE(1); | |
| // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| buf.writeShortLE(1); | |
| // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| buf.writeShortLE(1); | |
| // Desktop width and height (LE) | |
| buf.writeShortLE(screen.getFramebufferWidth()); | |
| buf.writeShortLE(screen.getFramebufferHeight()); | |
| // Padding 2 bytes | |
| buf.writeShortLE(0); | |
| // desktopResizeFlag (LE) | |
| buf.writeShortLE((desktopResize) ? 1 : 0); | |
| buf.writeBytes(new byte[] { | |
| (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE | |
| // (0x1)): TRUE (0x1) (LE) | |
| (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to | |
| // zero): 0 | |
| (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ??? | |
| (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| }); | |
| } | |
| private void writeOrderCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Order Capability Set (88 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240556.aspx | |
| (byte)0x03, | |
| (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE) | |
| (byte)0x58, | |
| (byte)0x00, // length of capability set: 88 bytes (LE) | |
| // terminalDescriptor = "" (16 bytes, UCS2) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA | |
| (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE) | |
| (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE) | |
| (byte)0x00, (byte)0x00, // pad2octetsA (ignored) | |
| (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1) | |
| (byte)0x00, (byte)0x00, // number of fonts (ignored): 0 | |
| (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE), | |
| // SOLIDPATTERNBRUSHONLY (0x40), | |
| // ZEROBOUNDSDELTASSUPPORT (0x8, MUST), | |
| // NEGOTIATEORDERSUPPORT (0x2, MUST) | |
| // Order support: 32 bytes (no primary drawing orders are supported, so | |
| // this array MUST be initialized to all zeros, use 0x01 for TRUE). | |
| (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE | |
| (byte)0x00, // Unused: 0 | |
| (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // Unused: 0 | |
| (byte)0x00, (byte)0x00, // Text flags (ignored): 0 (LE) | |
| (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size | |
| // (ignored): 0 | |
| // (assumed to be | |
| // 230400 bytes | |
| // (480*480, | |
| // 0x38400, LE)) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252, ANSI - Latin I | |
| // (0x04e4, LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| }); | |
| } | |
| private void writeSoundCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Sound Capability Set (8 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240552.aspx | |
| (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12, | |
| // LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags: | |
| // 0x0000 (LE) // | |
| // SOUND_FLAG_BEEPS | |
| // (0x1) | |
| }); | |
| } | |
| private void writeFontCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Font Capability Set (8 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240571.aspx | |
| (byte)0x0e, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, | |
| }); | |
| } | |
| private void writeOffscreenBitmapCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Offscreen Bitmap Cache Capability Set (12 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240550.aspx | |
| (byte)0x11, (byte)0x00, // capability set type: | |
| // CAPSTYPE_OFFSCREENCACHE (17, LE) | |
| (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel: | |
| // FALSE (LE) | |
| (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE) | |
| (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE) | |
| }); | |
| } | |
| private void writeGlyphCacheCS(ByteBuffer buf) { | |
| numberCapabilities++; | |
| buf.writeBytes(new byte[] { | |
| // | |
| // Glyph Cache Capability Set (52 bytes), see | |
| // http://msdn.microsoft.com/en-us/library/cc240565.aspx | |
| (byte)0x10, (byte)0x00, // capability set type: | |
| // CAPSTYPE_OFFSCREENCACHE (16, LE) | |
| (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE) | |
| // Glyph Cache (40 bytes) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE) | |
| (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE) | |
| // FragCache | |
| (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE) | |
| (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE) | |
| // | |
| (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0, | |
| // LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| }); | |
| } | |
| /** | |
| * Example. | |
| */ | |
| public static void main(String args[]) { | |
| // System.setProperty("streamer.Link.debug", "true"); | |
| System.setProperty("streamer.Element.debug", "true"); | |
| // System.setProperty("streamer.Pipeline.debug", "true"); | |
| /* @formatter:off */ | |
| byte[] packet = new byte[] { | |
| // MCS Send Data Request | |
| (byte)0x64, | |
| // Initiator: 1004 (1001+3) | |
| (byte)0x00, (byte)0x03, | |
| // Channel ID: 1003 (I/O channel) | |
| (byte)0x03, (byte)0xeb, | |
| // Data priority: high (0x40), segmentation: begin (0x20) | end (0x10) | |
| (byte)0x70, | |
| // User data length: 432 bytes (0x1b0, variable length field) | |
| (byte)0x81, (byte)0xb0, | |
| // Total length: 432 bytes (0x1b0, LE) | |
| (byte)0xb0, (byte)0x01, | |
| // PDU type: Confirm Active PDU (0x3), TS_PROTOCOL_VERSION (0x10) (LE) | |
| (byte)0x13, (byte)0x00, | |
| // PDU source: 1004 (LE) | |
| (byte)0xec, (byte)0x03, | |
| // Share ID: 0x000103ea (LE) | |
| (byte)0xea, (byte)0x03, (byte)0x01, (byte)0x00, | |
| // Originator ID: 1002 (LE) | |
| (byte)0xea, (byte)0x03, | |
| // Length of source descriptor: 6 bytes (including NULL character) (LE) | |
| (byte)0x06, (byte)0x00, | |
| // Length of combined capabilities: 410 bytes (LE) | |
| (byte)0x9a, (byte)0x01, | |
| // Source descriptor: "MSTSC" ??? | |
| (byte)0x4d, (byte)0x53, (byte)0x54, (byte)0x53, (byte)0x43, (byte)0x00, | |
| // Number of capabilities: 15 (LE) | |
| (byte)0x0f, (byte)0x00, | |
| // Padding 2 bytes | |
| (byte)0x00, (byte)0x00, | |
| // Capabilities, see http://msdn.microsoft.com/en-us/library/cc240486.aspx | |
| // | |
| // General capability set (24 bytes), see http://msdn.microsoft.com/en-us/library/cc240549.aspx | |
| (byte)0x01, (byte)0x00, // capability set type: CAPSTYPE_GENERAL (1) (LE) | |
| (byte)0x18, (byte)0x00, // length of capability set: 24 bytes (LE) | |
| (byte)0x01, (byte)0x00, // TS_OSMAJORTYPE_WINDOWS (1) (LE) | |
| (byte)0x03, (byte)0x00, // TS_OSMINORTYPE_WINDOWS_NT (3) (LE) | |
| (byte)0x00, (byte)0x02, // TS_CAPS_PROTOCOLVERSION (0x0200) (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0x00, (byte)0x00, // generalCompressionTypes: 0 (LE) | |
| // Extra flags: 0x040d (LE) | |
| // FastPathOutput: (...............1) Advertiser supports fast-path output | |
| // ShadowCompression: (..............0.) Advertiser NOT supports shadow compression | |
| // LongLengthCredentials: (.............1..) Advertiser supports long-length credentials for the user name, password, or domain name | |
| // SessionAutoreconnection: (............1...) Advertiser supports session auto-reconnection | |
| // ImprovedEncryptionChecksum: (...........0....) Client and server NOT support improved encryption checksum | |
| // Reserved1: (......00000.....) | |
| // CompressedBitMapDataFlag: (.....1..........) No 8-UINT8 header is present for compressed bitmap data | |
| // Reserved2: (00000...........) | |
| (byte)0x0d, (byte)0x04, | |
| (byte)0x00, (byte)0x00, // updateCapabilityFlag: 0 (LE) | |
| (byte)0x00, (byte)0x00, // remoteUnshareFlag: 0 (LE) | |
| (byte)0x00, (byte)0x00, // generalCompressionLevel: 0 (LE) | |
| (byte)0x00, // refreshRectSupport: FALSE (0) | |
| (byte)0x00, // suppressOutputSupport: FALSE (0) | |
| // | |
| // Bitmap capability set (28 bytes), see http://msdn.microsoft.com/en-us/library/cc240554.aspx | |
| (byte)0x02, (byte)0x00, // capability set type: CAPSTYPE_BITMAP (2) (LE) | |
| (byte)0x1c, (byte)0x00, // length of capability set: 28 bytes (LE) | |
| (byte)0x10, (byte)0x00, // preferredBitsPerPixel: 16 bpp (LE) | |
| (byte)0x01, (byte)0x00, // receive1BitPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| (byte)0x01, (byte)0x00, // receive4BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| (byte)0x01, (byte)0x00, // receive8BitsPerPixel (ignored and SHOULD be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| (byte)0x00, (byte)0x04, // desktopWidth = 1024 pixels (LE) | |
| (byte)0x00, (byte)0x03, // desktopHeight = 768 pixels (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0x00, (byte)0x00, // desktopResizeFlag: FALSE (0x0) (LE) | |
| (byte)0x01, (byte)0x00, // bitmapCompressionFlag (must be set to TRUE (0x1)): TRUE (0x1) (LE) | |
| (byte)0x00, // highColorFlags (field is ignored and SHOULD be set to zero): 0 | |
| (byte)0x01, // drawingFlags: 0x1 TODO: padding, why 0x1 ??? | |
| (byte)0x01, (byte)0x00, // multipleRectangleSupport: TRUE (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| // | |
| // Order Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240556.aspx | |
| (byte)0x03, (byte)0x00, // capability set type: CAPSTYPE_ORDER (3) (LE) | |
| (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE) | |
| // terminalDescriptor = "" (16 bytes, UCS2) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // pad4octetsA | |
| (byte)0x01, (byte)0x00, // desktopSaveXGranularity (ignored): 1 (LE) | |
| (byte)0x14, (byte)0x00, // desktopSaveYGranularity (ignored): 20 (LE) | |
| (byte)0x00, (byte)0x00, // pad2octetsA (ignored) | |
| (byte)0x01, (byte)0x00, // maximumOrderLevel: ORD_LEVEL_1_ORDERS (1) | |
| (byte)0x00, (byte)0x00, // number of fonts (ignored): 0 | |
| (byte)0x4a, (byte)0x00, // orderFlags = 0x004a (LE), SOLIDPATTERNBRUSHONLY (0x40), ZEROBOUNDSDELTASSUPPORT (0x8, MUST), NEGOTIATEORDERSUPPORT (0x2, MUST) | |
| // Order support: 32 bytes (no primary drawing orders are supported, so this array MUST be initialized to all zeros, use 0x01 for TRUE). | |
| (byte)0x00, // TS_NEG_DSTBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_PATBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_SCRBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEMBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEM3BLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_ATEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_AEXTTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_DRAWNINEGRID_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_LINETO_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTI_DRAWNINEGRID_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_OPAQUERECT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_SAVEBITMAP_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEMBLT_R2_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MEM3BLT_R2_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTIDSTBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTIPATBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTISCRBLT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_MULTIOPAQUERECT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_FAST_INDEX_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_POLYGON_SC_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_POLYGON_CB_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_POLYLINE_INDEX: TRUE | |
| (byte)0x00, // Unused: 0 | |
| (byte)0x00, // TS_NEG_FAST_GLYPH_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_ELLIPSE_SC_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_ELLIPSE_CB_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_INDEX_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WEXTTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WLONGTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // TS_NEG_WLONGEXTTEXTOUT_INDEX: FALSE | |
| (byte)0x00, // Unused: 0 | |
| (byte)0x00, (byte)0x00, // Text flags (ignored): 0 (LE) | |
| (byte)0x00, (byte)0x00, // Order support extra flags: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 4 bytes | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Desktop save size (ignored): 0 (assumed to be 230400 bytes (480*480, 0x38400, LE)) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0xe4, (byte)0x04, // Text ANSI Code Page: 1252, ANSI - Latin I (0x04e4, LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| // | |
| // Bitmap Cache Rev. 2 Capability Set (40 bytes), see http://msdn.microsoft.com/en-us/library/cc240560.aspx | |
| (byte)0x13, (byte)0x00, // capability set type: CAPSTYPE_BITMAPCACHE_REV2 (19) (LE) | |
| (byte)0x28, (byte)0x00, // length of capability set: 40 bytes (LE) | |
| (byte)0x00, (byte)0x00, // Cache flags: 0 (LE) | |
| (byte)0x00, // Padding 1 byte | |
| (byte)0x00, // Number of cell caches: 0 | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache0 cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache1 cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache2 cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache3 cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Bitmap cache4 cell info: 0 (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding 12 bytes | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // Padding | |
| // | |
| // Color Table Cache Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc241564.aspx | |
| (byte)0x0a, (byte)0x00, // capability set type: CAPSTYPE_COLORCACHE (10) (LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x06, (byte)0x00, // Color table cache size (must be ignored during capability exchange and is assumed to be 0x0006): 6 (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| // | |
| // Window Activation Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240569.aspx | |
| (byte)0x07, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7) (LE) | |
| (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE) | |
| (byte)0x00, (byte)0x00, // helpKeyFlag (should be set to FALSE (0)): FALSE (0, LE) | |
| (byte)0x00, (byte)0x00, // helpKeyIndexFlag (should be set to FALSE (0)): FALSE (0, LE) | |
| (byte)0x00, (byte)0x00, // helpExtendedKeyFlag (should be set to FALSE (0)): FALSE (0, LE) | |
| (byte)0x00, (byte)0x00, // windowManagerKeyFlag (should be set to FALSE (0)): FALSE (0, LE) | |
| // | |
| // Control Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240568.aspx | |
| (byte)0x05, (byte)0x00, // capability set type: CAPSTYPE_ACTIVATION (7) | |
| (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE) | |
| (byte)0x00, (byte)0x00, // controlFlags (should be set to 0): 0 (LE) | |
| (byte)0x00, (byte)0x00, // remoteDetachFlag (should be set to 0): 0 (LE) | |
| (byte)0x02, (byte)0x00, // controlInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE) | |
| (byte)0x02, (byte)0x00, // detachInterest (should be set to CONTROLPRIORITY_NEVER): CONTROLPRIORITY_NEVER (2) (LE) | |
| // | |
| // Pointer Capability Set (10 bytes), see http://msdn.microsoft.com/en-us/library/cc240562.aspx | |
| (byte)0x08, (byte)0x00, // capability set type: CAPSTYPE_POINTER (8, LE) | |
| (byte)0x0a, (byte)0x00, // length of capability set: 10 bytes (LE) | |
| (byte)0x00, (byte)0x00, // colorPointerFlag: FALSE (LE) | |
| (byte)0x00, (byte)0x00, // colorPointerCacheSize: 0 (LE) | |
| (byte)0x14, (byte)0x00, // pointerCacheSize: 20 (LE) | |
| // | |
| // Share Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240570.aspx | |
| (byte)0x09, (byte)0x00, // capability set type: CAPSTYPE_SHARE (9, LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x00, (byte)0x00, // nodeID (must be set to 0 by client): 0 (LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes (LE) | |
| // | |
| // Input Capability Set (88 bytes), see http://msdn.microsoft.com/en-us/library/cc240563.aspx | |
| (byte)0x0d, (byte)0x00, // capability set type: CAPSTYPE_INPUT (13, LE) | |
| (byte)0x58, (byte)0x00, // length of capability set: 88 bytes (LE) | |
| (byte)0x35, (byte)0x00, // inputFlags: 0x0035 (LE), INPUT_FLAG_FASTPATH_INPUT2 (0x20), INPUT_FLAG_VKPACKET (0x10), INPUT_FLAG_MOUSEX (0x4), INPUT_FLAG_SCANCODES (0x1) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| (byte)0x09, (byte)0x04, (byte)0x00, (byte)0x00, // keyboardLayout: "US" keyboard layout (0x000409, LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardType: unknown (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardSubType: unknown (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // keyboardFunctionKey: unknown (LE) | |
| // imeFileName: "", (64 bytes, including trailing NULL characters, UCS2) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, | |
| // | |
| // Brush Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240564.aspx | |
| (byte)0x0f, (byte)0x00, // capability set type: CAPSTYPE_BRUSH (15, LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // brushSupportLevel: BRUSH_DEFAULT (0x0, LE) | |
| // | |
| // Sound Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240552.aspx | |
| (byte)0x0c, (byte)0x00, // capability set type: CAPSTYPE_SOUND (12, LE) | |
| (byte)0x08, (byte)0x00, // length of capability set: 8 bytes (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // soundFlags: 0x0000 (LE) // SOUND_FLAG_BEEPS (0x1) | |
| // | |
| // Font Capability Set (8 bytes), see http://msdn.microsoft.com/en-us/library/cc240571.aspx | |
| (byte)0x0e, (byte)0x00, | |
| (byte)0x08, (byte)0x00, | |
| (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, | |
| // | |
| // Offscreen Bitmap Cache Capability Set (12 bytes), see http://msdn.microsoft.com/en-us/library/cc240550.aspx | |
| (byte)0x11, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (17, LE) | |
| (byte)0x0c, (byte)0x00, // length of capability set: 12 bytes (LE) | |
| (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // offscreenSupportLevel: FALSE (LE) | |
| (byte)0x00, (byte)0x00, // offscreenCacheSize: 0 (LE) | |
| (byte)0x00, (byte)0x00, // offscreenCacheEntries: 0 (LE) | |
| // | |
| // Glyph Cache Capability Set (52 bytes), see http://msdn.microsoft.com/en-us/library/cc240565.aspx | |
| (byte)0x10, (byte)0x00, // capability set type: CAPSTYPE_OFFSCREENCACHE (16, LE) | |
| (byte)0x34, (byte)0x00, // length of capability set: 52 bytes (LE) | |
| // Glyph Cache (40 bytes) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x04, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x08, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x10, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x20, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x40, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x80, (byte)0x00, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0xfe, (byte)0x00, // CacheEntries: 254 (LE) | |
| (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 4 (LE) | |
| (byte)0x40, (byte)0x00, // CacheEntries: 64 (LE) | |
| (byte)0x00, (byte)0x08, // CacheMaximumCellSize: 2048 (LE) | |
| // FragCache | |
| (byte)0x00, (byte)0x01, // CacheEntries: 256 (LE) | |
| (byte)0x00, (byte)0x01, // CacheMaximumCellSize: 256 (LE) | |
| // | |
| (byte)0x00, (byte)0x00, // GlyphSupportLevel: GLYPH_SUPPORT_NONE (0x0, LE) | |
| (byte)0x00, (byte)0x00, // Padding 2 bytes | |
| }; | |
| /* @formatter:on */ | |
| RdpState rdpState = new RdpState(); | |
| ScreenDescription screenDescription = new ScreenDescription(); | |
| screenDescription.setFramebufferSize(1024, 768); | |
| rdpState.serverShareId = 0x000103ea; | |
| MockSource source = new MockSource("source", ByteBuffer.convertByteArraysToByteBuffers(new byte[] {})); | |
| Element confirm_active = new ClientConfirmActivePDU("confirm_active", screenDescription, rdpState); | |
| Element sink = new MockSink("sink", ByteBuffer.convertByteArraysToByteBuffers(packet)); | |
| Pipeline pipeline = new PipelineImpl("test"); | |
| pipeline.add(source, confirm_active, sink); | |
| pipeline.link("source", "confirm_active", "sink"); | |
| pipeline.runMainLoop("source", STDOUT, false, false); | |
| } | |
| } |