2 * FreeRDP: A Remote Desktop Protocol client.
3 * File System Virtual Channel
5 * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Copyright 2010-2011 Vic Lee
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
25 #include <freerdp/utils/stream.h>
26 #include <freerdp/utils/svc_plugin.h>
28 #include "rdpdr_types.h"
29 #include "rdpdr_constants.h"
30 #include "rdpdr_capabilities.h"
32 /* Output device redirection capability set header */
33 static void rdpdr_write_capset_header(STREAM* data_out, uint16 capabilityType, uint16 capabilityLength, uint32 version)
35 stream_write_uint16(data_out, capabilityType);
36 stream_write_uint16(data_out, capabilityLength);
37 stream_write_uint32(data_out, version);
40 /* Output device direction general capability set */
41 static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, STREAM* data_out)
43 rdpdr_write_capset_header(data_out, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02);
45 stream_write_uint32(data_out, 0); /* osType, ignored on receipt */
46 stream_write_uint32(data_out, 0); /* osVersion, unused and must be set to zero */
47 stream_write_uint16(data_out, 1); /* protocolMajorVersion, must be set to 1 */
48 stream_write_uint16(data_out, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */
49 stream_write_uint32(data_out, 0x0000FFFF); /* ioCode1 */
50 stream_write_uint32(data_out, 0); /* ioCode2, must be set to zero, reserved for future use */
51 stream_write_uint32(data_out, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */
52 stream_write_uint32(data_out, ENABLE_ASYNCIO); /* extraFlags1 */
53 stream_write_uint32(data_out, 0); /* extraFlags2, must be set to zero, reserved for future use */
54 stream_write_uint32(data_out, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */
57 /* Process device direction general capability set */
58 static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, STREAM* data_in)
60 uint16 capabilityLength;
62 stream_read_uint16(data_in, capabilityLength);
63 stream_seek(data_in, capabilityLength - 4);
66 /* Output printer direction capability set */
67 static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, STREAM* data_out)
69 rdpdr_write_capset_header(data_out, CAP_PRINTER_TYPE, 8, PRINT_CAPABILITY_VERSION_01);
72 /* Process printer direction capability set */
73 static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, STREAM* data_in)
75 uint16 capabilityLength;
77 stream_read_uint16(data_in, capabilityLength);
78 stream_seek(data_in, capabilityLength - 4);
81 /* Output port redirection capability set */
82 static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, STREAM* data_out)
84 rdpdr_write_capset_header(data_out, CAP_PORT_TYPE, 8, PORT_CAPABILITY_VERSION_01);
87 /* Process port redirection capability set */
88 static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, STREAM* data_in)
90 uint16 capabilityLength;
92 stream_read_uint16(data_in, capabilityLength);
93 stream_seek(data_in, capabilityLength - 4);
96 /* Output drive redirection capability set */
97 static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, STREAM* data_out)
99 rdpdr_write_capset_header(data_out, CAP_DRIVE_TYPE, 8, DRIVE_CAPABILITY_VERSION_02);
102 /* Process drive redirection capability set */
103 static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, STREAM* data_in)
105 uint16 capabilityLength;
107 stream_read_uint16(data_in, capabilityLength);
108 stream_seek(data_in, capabilityLength - 4);
111 /* Output smart card redirection capability set */
112 static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, STREAM* data_out)
114 rdpdr_write_capset_header(data_out, CAP_SMARTCARD_TYPE, 8, SMARTCARD_CAPABILITY_VERSION_01);
117 /* Process smartcard redirection capability set */
118 static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, STREAM* data_in)
120 uint16 capabilityLength;
122 stream_read_uint16(data_in, capabilityLength);
123 stream_seek(data_in, capabilityLength - 4);
126 void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, STREAM* data_in)
129 uint16 numCapabilities;
130 uint16 capabilityType;
132 stream_read_uint16(data_in, numCapabilities);
133 stream_seek(data_in, 2); /* pad (2 bytes) */
135 for(i = 0; i < numCapabilities; i++)
137 stream_read_uint16(data_in, capabilityType);
139 switch (capabilityType)
141 case CAP_GENERAL_TYPE:
142 rdpdr_process_general_capset(rdpdr, data_in);
145 case CAP_PRINTER_TYPE:
146 rdpdr_process_printer_capset(rdpdr, data_in);
150 rdpdr_process_port_capset(rdpdr, data_in);
154 rdpdr_process_drive_capset(rdpdr, data_in);
157 case CAP_SMARTCARD_TYPE:
158 rdpdr_process_smartcard_capset(rdpdr, data_in);
162 DEBUG_WARN("Unknown capabilityType %d", capabilityType);
168 void rdpdr_send_capability_response(rdpdrPlugin* rdpdr)
172 data_out = stream_new(256);
174 stream_write_uint16(data_out, RDPDR_CTYP_CORE);
175 stream_write_uint16(data_out, PAKID_CORE_CLIENT_CAPABILITY);
177 stream_write_uint16(data_out, 5); /* numCapabilities */
178 stream_write_uint16(data_out, 0); /* pad */
180 rdpdr_write_general_capset(rdpdr, data_out);
181 rdpdr_write_printer_capset(rdpdr, data_out);
182 rdpdr_write_port_capset(rdpdr, data_out);
183 rdpdr_write_drive_capset(rdpdr, data_out);
184 rdpdr_write_smartcard_capset(rdpdr, data_out);
186 svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out);